This data setup stolen brazenly from Jennifer Thompson.

## Load libraries we'll use
# library(devtools)
# install_github('datadotworld/data.world-r')
library(data.world) ## for querying directly from data.world
library(tidyverse)  ## for data wrangling and piping
Loading tidyverse: ggplot2
Loading tidyverse: tibble
Loading tidyverse: tidyr
Loading tidyverse: readr
Loading tidyverse: purrr
Loading tidyverse: dplyr
Conflicts with tidy packages ------------------------------------------------------------------------------------
filter(): dplyr, stats
lag():    dplyr, stats
query():  dplyr, data.world
library(rms)        ## rms has nice functionality for getting predicted values from model objects
Loading required package: Hmisc
Loading required package: lattice
Loading required package: survival
Loading required package: Formula

Attaching package: 㤼㸱Hmisc㤼㸲

The following objects are masked from 㤼㸱package:dplyr㤼㸲:

    combine, src, summarize

The following objects are masked from 㤼㸱package:base㤼㸲:

    format.pval, round.POSIXt, trunc.POSIXt, units

Loading required package: SparseM

Attaching package: 㤼㸱SparseM㤼㸲

The following object is masked from 㤼㸱package:base㤼㸲:

    backsolve
library(scales)

Attaching package: 㤼㸱scales㤼㸲

The following object is masked from 㤼㸱package:purrr㤼㸲:

    discard

The following objects are masked from 㤼㸱package:readr㤼㸲:

    col_factor, col_numeric
library(reshape2)  

Attaching package: 㤼㸱reshape2㤼㸲

The following object is masked from 㤼㸱package:tidyr㤼㸲:

    smiths

We want to determine what county characteristics may be predictors of both the county’s final winner in the 2016 presidential election, and the margin of victory by which that candidate won.

Project Setup

Loading Data

We’ll load the county characteristics and 2016 presidential election results datasets directly from data.world.

County Characteristics

These data are mostly from the 2015 American Community Survey, with additional data from other sources. A full data dictionary can be found here.

library(data.world)
## Set connection (see package README for details: https://github.com/datadotworld/data.world-r)
conn<-data.world(read_csv('C:/Users/rkahne/Documents/data_world_api.csv')$key)
# ## What data tables are available? (both dplyr and data.world have a query(); must specify)
# data_list <- data.world::query(conn,
#                                dataset = 'data4democracy/election-transparency',
#                                query = "SELECT * FROM Tables")
# data_list
countyChar <- data.world::query(conn,
                                dataset = 'data4democracy/election-transparency',
                                query = "SELECT * FROM CountyCharacteristics")

Voter Registration

We also want party registration data from November 2016, queried from the full PartyRegistration file. This file includes data pulled from each state’s Secretary of State web site. Full data dictionary is here.

Some of the variable names overlap with names in the next dataset; we’ll drop variables that are redundant (state/county names/abbreviations and year/month of registration) and add “Reg” to everything else except state/county keys to clarify that it’s registration info.

voterReg2016 <-
  data.world::query(conn,
                    dataset = 'data4democracy/election-transparency',
                    query = "SELECT * FROM PartyRegistration WHERE Year = 2016 AND Month = 11")
voterReg2016 <- voterReg2016 %>%
  select(-one_of("CountyName", "StateName", "StateAbbr", "Year", "Month", "YearMonth"))
names(voterReg2016) <- ifelse(names(voterReg2016) %in% c('State', 'County'), names(voterReg2016),
                              paste0(names(voterReg2016), 'Reg'))

Presidential Election Results by County

These data are collected from a Harvard research project. A full data dictionary can be found here.

presResults2016 <- data.world::query(conn,
                                     dataset = 'data4democracy/election-transparency',
                                     query = "SELECT * FROM PresidentialElectionResults2016")

Descriptive Statistics

Let’s join the datasets, calculate some proportions, and look at some basic descriptive statistics.

## Check what variables are in common
# intersect(names(countyChar), names(voterReg2016))
# intersect(names(countyChar), names(presResults2016))
data2016 <- reduce(list(countyChar, voterReg2016, presResults2016),
                   left_join,
                   by = c('County', 'State'))
## Function to quickly calculate a proportion out of TotalPopulation - we'll need to do this a lot
prop_total <- function(x){ x / data2016$TotalPopulation }
data2016 <- data2016 %>%
  ## Calculate lots of proportion variables
  mutate(propMale = prop_total(Male),
         propKids = prop_total(Age0_4 + Age5_9 + Age10_14 + Age15_19),
         propAdultsNoTeens = 1 - propKids,
         ## 15-19 is included in labor force, marital status questions
         totalAdultsWithTeens = Age15_19 + Age20_24 + Age25_34 + Age35_44 + Age45_54 + Age55_59 +
           Age60_64 + Age65_74 + Age75_84 + Age85,
         propAdultsWithTeens = prop_total(totalAdultsWithTeens),
         ## Only >18 included in education questions
         totalAdultsNoTeens = Age20_24 + Age25_34 + Age35_44 + Age45_54 + Age55_59 + Age60_64 +
           Age65_74 + Age75_84 + Age85,
         propElders = prop_total(Age65_74 + Age75_84 + Age85),
         propNMarried = NeverMarried / totalAdultsWithTeens,
         propHispanic = prop_total(Hispanic),
         propWhite = prop_total(White),
         propBlack = prop_total(Black),
         majWhite = propWhite > 0.5,
         majBlack = propBlack > 0.5,
         propNoHS = (EdK8 + Ed9_12) / totalAdultsNoTeens,
         propHS = EdHS / totalAdultsNoTeens,
         propMoreHS = (EdCollNoDegree + EdAssocDegree + EdBachelorDegree + EdGraduateDegree) /
           totalAdultsNoTeens,
         propMfg2015 = MfgEmp2015 / LaborForce,
         propUnemp = Unemployment / LaborForce,
         propLaborForce = prop_total(LaborForce),
         propStein = stein / totalvotes,
         propJohnson = johnson / totalvotes,
         propTrump = trump / totalvotes,
         propClinton = clinton / totalvotes,
         propVoters = totalvotes / totalAdultsNoTeens,
         votedTrump = rPct > 0.5,
         state_EV = electoral_votes[StateName])
## View full data frame
data2016

Visualizations!

  • I made some small modifications to the code above, my modficiations mostly turned out to be useless, anyway.
  • I (rkahne) really started doing work around here.
  • The goal (for me, right now) is to build out dataframes from the great work done by Jennifer Thompson that can be used with ggplot.
  • I’ve done some Very Basic Barplots to get started. I hope other people can take this stuff, modify it, and find some cool and interesting stuff in here.

Candidate vote totals by State

vote_by_state<-select(data2016, StateName, state_EV, clinton, trump, johnson, stein, other) %>% 
  melt(id= c('StateName','state_EV')) %>% 
  group_by(StateName, state_EV, variable) %>% 
  dplyr::summarize(total_vote = sum(value)) %>% # Dunno how plyr got in, but whatever.
  complete(variable) %>%
  ungroup() %>% 
  group_by(StateName) %>% 
  mutate(sum_total = sum(total_vote, na.rm=T)) %>% 
  mutate(proportion = ifelse(is.na(total_vote),NA,paste0(round(total_vote / sum_total, 4)*100,'%')),
         proportion_numeric = total_vote / sum_total) %>%
  select(-sum_total)
candidate_order <- 'clinton' # CHANGE ME
level_order<-(filter(vote_by_state,variable == candidate_order) %>% 
                     select(StateName, proportion_numeric) %>% 
                     arrange(desc(proportion_numeric)))$StateName 
vote_by_state$StateName<- factor(vote_by_state$StateName, levels = level_order)
vote_by_state$variable<-factor(vote_by_state$variable, levels = c('other','stein','johnson','trump','clinton'))
ggplot(vote_by_state, aes(x=StateName, y=total_vote, fill=variable)) + 
  geom_bar(stat='identity', position = 'fill') +
  scale_fill_manual(values = c('clinton' = 'blue', 'trump' = 'red', 'stein' = 'green','johnson' = 'yellow','other' = 'purple'), 
                    name = 'Candidate',
                    breaks = c('other','stein','johnson','trump','clinton'),
                    labels = c('Others','Jill Stein','Gary Johnson','Donald J Trump','Hillary Clinton')) +
  labs(x = NULL, y = 'Percent of Vote')+
  scale_y_continuous(labels = scales::percent) +
  ggtitle('Percent of Vote by State', subtitle='2016 USA Presidential Election') +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Candidate Vote Totals by County Within State

Feel free to play with the variable in this chunk.

state<-'Tennessee'
vote_by_county<-filter(data2016, StateName == state) %>% 
  select(CountyName, clinton, trump, johnson, stein, other) %>% 
  melt(id= 'CountyName') %>% 
  group_by(CountyName, variable) %>% 
  dplyr::summarize(total_vote = sum(value)) %>% # Dunno how plyr got in, but whatever.
  complete(variable) %>%
  ungroup() %>% 
  group_by(CountyName) %>% 
  mutate(sum_total = sum(total_vote, na.rm=T)) %>% 
  mutate(proportion = ifelse(is.na(total_vote),NA,paste0(round(total_vote / sum_total, 4)*100,'%')),
         proportion_numeric = total_vote / sum_total) %>%
  select(-sum_total)
candidate_order <- 'clinton' # CHANGE ME
level_order<-(filter(vote_by_county,variable == candidate_order) %>% 
                     select(CountyName, proportion_numeric) %>% 
                     arrange(desc(proportion_numeric)))$CountyName 
vote_by_county$CountyName<- factor(vote_by_county$CountyName, levels = level_order)
vote_by_county$variable<-factor(vote_by_county$variable, levels = c('other','stein','johnson','trump','clinton'))
ggplot(vote_by_county, aes(x=CountyName, y=total_vote, fill=variable)) + 
  geom_bar(stat='identity', position = 'fill') +
  scale_fill_manual(values = c('clinton' = 'blue', 'trump' = 'red', 'stein' = 'green','johnson' = 'yellow','other' = 'purple'), 
                    name = 'Candidate',
                    breaks = c('other','stein','johnson','trump','clinton'),
                    labels = c('Others','Jill Stein','Gary Johnson','Donald J Trump','Hillary Clinton')) +
  labs(x = NULL, y = 'Percent of Vote')+
  scale_y_continuous(labels = scales::percent) +
  ggtitle(paste0('Percent of Vote by County - ',state), subtitle='2016 USA Presidential Election') +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Ternary Plot

  • Let’s try something crazy?!
  • Here’s an interesting idea for looking at the county by county results.
    • Utah had a high vote total for Evan McMillin, and this is a way to visualize Utah’s uniqueness.
library(ggtern)
ternary_vote<-mutate(data2016, third_party = johnson + stein + other) %>% 
  select(County, StateName, clinton, trump, third_party) %>% 
  melt(id= c('County','StateName')) %>% 
  group_by(County, StateName, variable) %>% 
  dplyr::summarize(total_vote = sum(value)) %>% # Dunno how plyr got in, but whatever.
  complete(variable) %>%
  ungroup() %>% 
  group_by(County) %>% 
  mutate(sum_total = sum(total_vote, na.rm=T)) %>% 
  mutate(proportion_numeric = total_vote / sum_total) %>%
  select(-sum_total, -total_vote) %>% 
  spread(key = variable, value = proportion_numeric)

|=========================                                                                                                       | 20% ~8 s remaining     
|==========================                                                                                                      | 21% ~8 s remaining     
|===========================                                                                                                     | 21% ~8 s remaining     
|===========================                                                                                                     | 22% ~8 s remaining     
|============================                                                                                                    | 22% ~8 s remaining     
|=============================                                                                                                   | 23% ~8 s remaining     
|==============================                                                                                                  | 24% ~8 s remaining     
|==============================                                                                                                  | 24% ~8 s remaining     
|===============================                                                                                                 | 25% ~8 s remaining     
|================================                                                                                                | 25% ~8 s remaining     
|================================                                                                                                | 26% ~8 s remaining     
|=================================                                                                                               | 26% ~8 s remaining     
|=================================                                                                                               | 26% ~8 s remaining     
|==================================                                                                                              | 27% ~8 s remaining     
|===================================                                                                                             | 28% ~7 s remaining     
|====================================                                                                                            | 29% ~7 s remaining     
|=====================================                                                                                           | 29% ~7 s remaining     
|=====================================                                                                                           | 29% ~7 s remaining     
|======================================                                                                                          | 30% ~7 s remaining     
|=======================================                                                                                         | 31% ~7 s remaining     
|========================================                                                                                        | 32% ~7 s remaining     
|=========================================                                                                                       | 33% ~7 s remaining     
|==========================================                                                                                      | 33% ~7 s remaining     
|===========================================                                                                                     | 34% ~7 s remaining     
|============================================                                                                                    | 35% ~7 s remaining     
|=============================================                                                                                   | 35% ~6 s remaining     
|==============================================                                                                                  | 36% ~6 s remaining     
|===============================================                                                                                 | 37% ~6 s remaining     
|================================================                                                                                | 38% ~6 s remaining     
|================================================                                                                                | 38% ~6 s remaining     
|=================================================                                                                               | 39% ~6 s remaining     
|==================================================                                                                              | 40% ~6 s remaining     
|===================================================                                                                             | 40% ~6 s remaining     
|===================================================                                                                             | 41% ~6 s remaining     
|====================================================                                                                            | 41% ~6 s remaining     
|=====================================================                                                                           | 42% ~6 s remaining     
|======================================================                                                                          | 42% ~6 s remaining     
|=======================================================                                                                         | 43% ~6 s remaining     
|=======================================================                                                                         | 44% ~6 s remaining     
|========================================================                                                                        | 44% ~6 s remaining     
|=========================================================                                                                       | 45% ~6 s remaining     
|=========================================================                                                                       | 45% ~6 s remaining     
|==========================================================                                                                      | 45% ~6 s remaining     
|==========================================================                                                                      | 46% ~5 s remaining     
|===========================================================                                                                     | 46% ~5 s remaining     
|===========================================================                                                                     | 46% ~5 s remaining     
|===========================================================                                                                     | 47% ~5 s remaining     
|============================================================                                                                    | 47% ~5 s remaining     
|=============================================================                                                                   | 48% ~5 s remaining     
|==============================================================                                                                  | 49% ~5 s remaining     
|==============================================================                                                                  | 49% ~5 s remaining     
|===============================================================                                                                 | 49% ~5 s remaining     
|===============================================================                                                                 | 50% ~5 s remaining     
|================================================================                                                                | 50% ~5 s remaining     
|================================================================                                                                | 50% ~5 s remaining     
|=================================================================                                                               | 51% ~5 s remaining     
|==================================================================                                                              | 52% ~5 s remaining     
|==================================================================                                                              | 52% ~5 s remaining     
|===================================================================                                                             | 53% ~5 s remaining     
|====================================================================                                                            | 53% ~5 s remaining     
|====================================================================                                                            | 54% ~5 s remaining     
|====================================================================                                                            | 54% ~5 s remaining     
|=====================================================================                                                           | 54% ~5 s remaining     
|=====================================================================                                                           | 55% ~5 s remaining     
|======================================================================                                                          | 55% ~5 s remaining     
|=======================================================================                                                         | 56% ~5 s remaining     
|=======================================================================                                                         | 56% ~5 s remaining     
|========================================================================                                                        | 57% ~5 s remaining     
|=========================================================================                                                       | 57% ~5 s remaining     
|=========================================================================                                                       | 58% ~4 s remaining     
|==========================================================================                                                      | 58% ~4 s remaining     
|===========================================================================                                                     | 59% ~4 s remaining     
|===========================================================================                                                     | 59% ~4 s remaining     
|============================================================================                                                    | 60% ~4 s remaining     
|============================================================================                                                    | 60% ~4 s remaining     
|=============================================================================                                                   | 61% ~4 s remaining     
|==============================================================================                                                  | 61% ~4 s remaining     
|==============================================================================                                                  | 61% ~4 s remaining     
|===============================================================================                                                 | 62% ~4 s remaining     
|===============================================================================                                                 | 62% ~4 s remaining     
|================================================================================                                                | 63% ~4 s remaining     
|================================================================================                                                | 63% ~4 s remaining     
|=================================================================================                                               | 63% ~4 s remaining     
|=================================================================================                                               | 64% ~4 s remaining     
|==================================================================================                                              | 64% ~4 s remaining     
|==================================================================================                                              | 65% ~4 s remaining     
|===================================================================================                                             | 65% ~4 s remaining     
|===================================================================================                                             | 65% ~4 s remaining     
|====================================================================================                                            | 66% ~4 s remaining     
|=====================================================================================                                           | 66% ~4 s remaining     
|=====================================================================================                                           | 67% ~4 s remaining     
|======================================================================================                                          | 68% ~4 s remaining     
|=======================================================================================                                         | 68% ~3 s remaining     
|=======================================================================================                                         | 68% ~3 s remaining     
|========================================================================================                                        | 69% ~3 s remaining     
|========================================================================================                                        | 69% ~3 s remaining     
|=========================================================================================                                       | 70% ~3 s remaining     
|==========================================================================================                                      | 70% ~3 s remaining     
|==========================================================================================                                      | 71% ~3 s remaining     
|===========================================================================================                                     | 71% ~3 s remaining     
|===========================================================================================                                     | 72% ~3 s remaining     
|===========================================================================================                                     | 72% ~3 s remaining     
|============================================================================================                                    | 72% ~3 s remaining     
|============================================================================================                                    | 72% ~3 s remaining     
|============================================================================================                                    | 72% ~3 s remaining     
|=============================================================================================                                   | 73% ~3 s remaining     
|=============================================================================================                                   | 73% ~3 s remaining     
|==============================================================================================                                  | 74% ~3 s remaining     
|===============================================================================================                                 | 74% ~3 s remaining     
|===============================================================================================                                 | 75% ~3 s remaining     
|================================================================================================                                | 75% ~3 s remaining     
|================================================================================================                                | 75% ~3 s remaining     
|================================================================================================                                | 76% ~3 s remaining     
|=================================================================================================                               | 76% ~3 s remaining     
|==================================================================================================                              | 77% ~3 s remaining     
|==================================================================================================                              | 77% ~3 s remaining     
|==================================================================================================                              | 77% ~3 s remaining     
|===================================================================================================                             | 78% ~3 s remaining     
|====================================================================================================                            | 78% ~3 s remaining     
|====================================================================================================                            | 79% ~2 s remaining     
|====================================================================================================                            | 79% ~2 s remaining     
|=====================================================================================================                           | 79% ~2 s remaining     
|======================================================================================================                          | 80% ~2 s remaining     
|======================================================================================================                          | 80% ~2 s remaining     
|=======================================================================================================                         | 81% ~2 s remaining     
|========================================================================================================                        | 82% ~2 s remaining     
|=========================================================================================================                       | 82% ~2 s remaining     
|=========================================================================================================                       | 82% ~2 s remaining     
|=========================================================================================================                       | 82% ~2 s remaining     
|=========================================================================================================                       | 83% ~2 s remaining     
|==========================================================================================================                      | 83% ~2 s remaining     
|===========================================================================================================                     | 84% ~2 s remaining     
|============================================================================================================                    | 85% ~2 s remaining     
|=============================================================================================================                   | 86% ~2 s remaining     
|==============================================================================================================                  | 86% ~2 s remaining     
|===============================================================================================================                 | 87% ~2 s remaining     
|================================================================================================================                | 88% ~1 s remaining     
|================================================================================================================                | 88% ~1 s remaining     
|=================================================================================================================               | 89% ~1 s remaining     
|=================================================================================================================               | 89% ~1 s remaining     
|=================================================================================================================               | 89% ~1 s remaining     
|=================================================================================================================               | 89% ~1 s remaining     
|==================================================================================================================              | 89% ~1 s remaining     
|===================================================================================================================             | 90% ~1 s remaining     
|===================================================================================================================             | 90% ~1 s remaining     
|===================================================================================================================             | 90% ~1 s remaining     
|====================================================================================================================            | 91% ~1 s remaining     
|====================================================================================================================            | 91% ~1 s remaining     
|=====================================================================================================================           | 92% ~1 s remaining     
|=====================================================================================================================           | 92% ~1 s remaining     
|======================================================================================================================          | 92% ~1 s remaining     
|======================================================================================================================          | 93% ~1 s remaining     
|=======================================================================================================================         | 94% ~1 s remaining     
|========================================================================================================================        | 94% ~1 s remaining     
|==========================================================================================================================      | 95% ~1 s remaining     
|===========================================================================================================================     | 96% ~0 s remaining     
|============================================================================================================================    | 97% ~0 s remaining     
|=============================================================================================================================   | 98% ~0 s remaining     
|==============================================================================================================================  | 99% ~0 s remaining     
|==============================================================================================================================  | 99% ~0 s remaining     
|=============================================================================================================================== | 99% ~0 s remaining     
|=============================================================================================================================== |100% ~0 s remaining     
ternary_vote$StateName<-sapply(ternary_vote$StateName, function(i) ifelse(i=='Utah','Utah','Not Utah'))
ggtern(ternary_vote, aes(x=clinton, y=trump, z=third_party, color=StateName))+
  geom_point(aes(alpha = 0.2))

Party Registration by State

Not all states have partisan registration.

party_registration <- select(voterReg2016, State, DReg, RReg, OReg, GReg, LReg, NReg) %>% 
  melt(id= 'State') %>% 
  group_by(State, variable) %>% 
  dplyr::summarize(total_reg = sum(value)) %>% 
  complete(variable) %>%
  ungroup() %>% 
  group_by(State) %>% 
  mutate(sum_total = sum(total_reg, na.rm=T)) %>% 
  mutate(proportion = ifelse(is.na(total_reg),NA,paste0(round(total_reg / sum_total, 4)*100,'%')),
         proportion_numeric = total_reg / sum_total) %>%
  select(-sum_total)
party_registration$State<-sapply(party_registration$State, function(i) names(state_names)[which(state_names == i)])
non_partisan_states<-(filter(party_registration, variable == 'NReg') %>% 
                        filter(proportion_numeric == 1))$State
party_registration <- filter(party_registration, !(State %in% non_partisan_states))
party_order <- 'DReg' # CHANGE ME
level_order<-(filter(party_registration,variable == party_order) %>% 
                     select(State, proportion_numeric) %>% 
                     arrange(desc(proportion_numeric)))$State
party_registration$State<- factor(party_registration$State, levels = level_order)
party_registration$variable<-factor(party_registration$variable, levels = c('NReg','OReg','GReg','LReg','RReg','DReg'))
ggplot(party_registration, aes(x=State, y=total_reg, fill=variable)) + 
  geom_bar(stat='identity', position = 'fill') +
  scale_fill_manual(values = c('DReg' = 'blue', 'RReg' = 'red', 'GReg' = 'green','LReg' = 'yellow','OReg' = 'purple','NReg' = 'grey'),
                    name = 'Candidate',
                    breaks = c('NReg','OReg','GReg','LReg','RReg','DReg'),
                    labels = c('No Party','Other Party','Green','Libertarian','Republican','Democratic')) +
  labs(x = NULL, y = 'Percent of Registered Voters')+
  scale_y_continuous(labels = scales::percent) +
  ggtitle('Percent of Voter Registration by State', subtitle='2016') +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Looks like we have a bit of an issue here with Other and Non-partisan registration. NE and WV are all “Other”.

Partisan Registration by County within State

Feel free to play with the variable in this.

state <- 'West Virginia'
party_registration_c <- filter(data2016, StateName == state) %>%  
  select(CountyName, DReg, RReg, OReg, GReg, LReg, NReg) %>% 
  melt(id= 'CountyName') %>% 
  group_by(CountyName, variable) %>% 
  dplyr::summarize(total_reg = sum(value)) %>% 
  complete(variable) %>%
  ungroup() %>% 
  group_by(CountyName) %>% 
  mutate(sum_total = sum(total_reg, na.rm=T)) %>% 
  mutate(proportion = ifelse(is.na(total_reg),NA,paste0(round(total_reg / sum_total, 4)*100,'%')),
         proportion_numeric = total_reg / sum_total) %>%
  select(-sum_total)
party_order <- 'DReg' # CHANGE ME
level_order<-(filter(party_registration_c,variable == party_order) %>% 
                     select(CountyName, proportion_numeric) %>% 
                     arrange(desc(proportion_numeric)))$CountyName
party_registration_c$CountyName<- factor(party_registration_c$CountyName, levels = level_order)
party_registration_c$variable<-factor(party_registration_c$variable, levels = c('NReg','OReg','GReg','LReg','RReg','DReg'))
ggplot(party_registration_c, aes(x=CountyName, y=total_reg, fill=variable)) + 
  geom_bar(stat='identity', position = 'fill') +
  scale_fill_manual(values = c('DReg' = 'blue', 'RReg' = 'red', 'GReg' = 'green','LReg' = 'yellow','OReg' = 'purple','NReg' = 'grey'),
                    name = 'Candidate',
                    breaks = c('NReg','OReg','GReg','LReg','RReg','DReg'),
                    labels = c('No Party','Other Party','Green','Libertarian','Republican','Democratic')) +
  labs(x = NULL, y = 'Percent of Registered Voters')+
  scale_y_continuous(labels = scales::percent) +
  ggtitle('Percent of Voter Registration by County', subtitle=paste0(state,' - 2016')) +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Voter Turnout by State

  • We don’t have great data to do this, becuase the census bracket is from age 15-19, which cuts out two years of voting age.
  • Maybe because of this (but maybe not!) there are some states where (voted+registered but didn’t vote) > total voting population.
    • Even if the issue is not the census populations, it could be merely out of date voter registration data.
turnout_data <- group_by(data2016, StateName) %>% 
  dplyr::summarize(total_votes = sum(clinton,trump,johnson,stein,other, na.rm=T),
                   total_reg_no_vote = sum(DReg,RReg,OReg,GReg,LReg,NReg, na.rm=T)-total_votes,
                   total_not_registered = ifelse(sum(TotalPopulation)- sum(Age0_4)- sum(Age5_9)- sum(Age10_14) - sum(Age15_19) -
                     total_reg_no_vote - total_votes<0,NA,sum(TotalPopulation)- sum(Age0_4)- sum(Age5_9)- sum(Age10_14) - 
                     sum(Age15_19) - total_reg_no_vote - total_votes)) %>%  
  melt(id = 'StateName') %>% 
  group_by(StateName, variable) %>% 
  dplyr::summarize(total_pop = sum(value)) %>% 
  complete(variable) %>%
  ungroup() %>% 
  group_by(StateName) %>% 
  mutate(sum_total = sum(total_pop, na.rm=T)) %>% 
  mutate(proportion = ifelse(is.na(total_pop),NA,paste0(round(total_pop / sum_total, 4)*100,'%')),
         proportion_numeric = total_pop / sum_total) %>%
  select(-sum_total)
turnout_data$variable<-factor(turnout_data$variable, levels = c('total_not_registered','total_reg_no_vote','total_votes'))
ggplot(turnout_data, aes(x=StateName, y=total_pop, fill=variable)) + 
  geom_bar(stat='identity', position = 'fill') +
  scale_fill_manual(values = c('total_votes' = 'green', 'total_reg_no_vote' = 'purple', 'total_not_registered' = 'grey'),
                    name = 'Population',
                    breaks = c('total_votes','total_reg_no_vote','total_not_registered'),
                    labels = c('Voted','Registered, but did not vote','Not Registered')) +
  labs(x = NULL, y = 'Percent of Population')+
  scale_y_continuous(labels = scales::percent) +
  ggtitle('Voter Turnout by State', subtitle='2016') +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Voter Turnout by County Within State

state <- 'Kentucky'
turnout_data_c <- filter(data2016, StateName == state) %>% 
  group_by(CountyName) %>% 
  dplyr::summarize(total_votes = sum(clinton,trump,johnson,stein,other, na.rm=T),
                   total_reg_no_vote = sum(DReg,RReg,OReg,GReg,LReg,NReg, na.rm=T)-total_votes,
                   total_not_registered = ifelse(sum(TotalPopulation)- sum(Age0_4)- sum(Age5_9)- sum(Age10_14) - sum(Age15_19) -
                     total_reg_no_vote - total_votes<0,NA,sum(TotalPopulation)- sum(Age0_4)- sum(Age5_9)- sum(Age10_14) - 
                     sum(Age15_19) - total_reg_no_vote - total_votes)) %>%  
  melt(id = 'CountyName') %>% 
  group_by(CountyName, variable) %>% 
  dplyr::summarize(total_pop = sum(value)) %>% 
  complete(variable) %>%
  ungroup() %>% 
  group_by(CountyName) %>% 
  mutate(sum_total = sum(total_pop, na.rm=T)) %>% 
  mutate(proportion = ifelse(is.na(total_pop),NA,paste0(round(total_pop / sum_total, 4)*100,'%')),
         proportion_numeric = total_pop / sum_total) %>%
  select(-sum_total)
turnout_data_c$variable<-factor(turnout_data_c$variable, levels = c('total_not_registered','total_reg_no_vote','total_votes'))
ggplot(turnout_data_c, aes(x=CountyName, y=total_pop, fill=variable)) + 
  geom_bar(stat='identity', position = 'fill') +
  scale_fill_manual(values = c('total_votes' = 'green', 'total_reg_no_vote' = 'purple', 'total_not_registered' = 'grey'),
                    name = 'Population',
                    breaks = c('total_votes','total_reg_no_vote','total_not_registered'),
                    labels = c('Voted','Registered, but did not vote','Not Registered')) +
  labs(x = NULL, y = 'Percent of Population')+
  scale_y_continuous(labels = scales::percent) +
  ggtitle('Voter Turnout by County', subtitle=paste0(state,', 2016')) +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Victory Margins

  • Not quite sure what we are going for, here.

Demographic / Economic Variables

  • Let’s look at % of vote faceted over some different variables
  • This graphic produces county by county results facetting by quintile of Demographic/Economic variable
    • You can change the variable in the code to see other variables.
  • There is one categorical variable, the code for producing it’s facetted plot is in commented in this chunk.
Demo_Factors <- select(data2016, County, rDRPct, NCHS_UrbanRural2013, TotalPopulation, MedianAge, MedianHouseholdIncome, SimpsonDiversityIndex, propWhite, propBlack, propMfg2015, propHS, propMoreHS, propUnemp, propElders, propNMarried)
lm(rDRPct~.,select(Demo_Factors,-County)) %>% summary()

Call:
lm(formula = rDRPct ~ ., data = select(Demo_Factors, -County))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.60295 -0.04971  0.00257  0.05506  0.34930 

Coefficients:
                                                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)                                        1.032e+00  5.994e-02  17.218  < 2e-16 ***
NCHS_UrbanRural2013Large fringe metro              2.919e-02  1.512e-02   1.931 0.053553 .  
NCHS_UrbanRural2013Medium metro                    1.546e-02  1.505e-02   1.027 0.304418    
NCHS_UrbanRural2013Micropolitan (nonmetropolitan)  3.160e-02  1.549e-02   2.040 0.041463 *  
NCHS_UrbanRural2013Noncore (nonmetropolitan)       5.146e-02  1.566e-02   3.286 0.001031 ** 
NCHS_UrbanRural2013Small metro                     3.236e-02  1.558e-02   2.077 0.037899 *  
TotalPopulation                                   -4.223e-08  6.863e-09  -6.154 8.68e-10 ***
MedianAge                                         -1.429e-02  9.947e-04 -14.370  < 2e-16 ***
MedianHouseholdIncome                             -6.213e-07  2.608e-07  -2.382 0.017284 *  
SimpsonDiversityIndex                              2.227e-01  2.577e-02   8.641  < 2e-16 ***
propWhite                                          5.219e-01  3.796e-02  13.748  < 2e-16 ***
propBlack                                          9.281e-02  2.814e-02   3.298 0.000987 ***
propMfg2015                                       -2.879e-04  5.838e-04  -0.493 0.621911    
propHS                                             3.440e-01  5.481e-02   6.275 4.04e-10 ***
propMoreHS                                        -2.194e-01  4.255e-02  -5.156 2.70e-07 ***
propUnemp                                          3.636e-05  5.378e-04   0.068 0.946102    
propElders                                         5.882e-01  1.140e-01   5.159 2.66e-07 ***
propNMarried                                      -1.490e+00  4.423e-02 -33.682  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.0898 on 2736 degrees of freedom
  (387 observations deleted due to missingness)
Multiple R-squared:  0.6721,    Adjusted R-squared:  0.6701 
F-statistic: 329.9 on 17 and 2736 DF,  p-value: < 2.2e-16
Demo_Factors <- select(data2016, County, trump, clinton, johnson, stein, other, NCHS_UrbanRural2013, TotalPopulation, MedianAge, MedianHouseholdIncome, SimpsonDiversityIndex, propWhite, propBlack, propMfg2015, propHS, propMoreHS, propUnemp, propElders, propNMarried)
vote_by_county_f<-select(Demo_Factors, County, clinton, trump, johnson, stein, other) %>% 
  melt(id= c('County')) %>% 
  group_by(County, variable) %>% 
  dplyr::summarize(total_vote = sum(value)) %>% # Dunno how plyr got in, but whatever.
  complete(variable) %>%
  ungroup() %>% 
  group_by(County) %>% 
  mutate(sum_total = sum(total_vote, na.rm=T)) %>% 
  mutate(proportion = ifelse(is.na(total_vote),NA,paste0(round(total_vote / sum_total, 4)*100,'%')),
         proportion_numeric = total_vote / sum_total) %>%
  select(-sum_total)

|=========================                                                                                                       | 20% ~8 s remaining     
|==========================                                                                                                      | 20% ~8 s remaining     
|==========================                                                                                                      | 21% ~8 s remaining     
|===========================                                                                                                     | 22% ~8 s remaining     
|============================                                                                                                    | 22% ~8 s remaining     
|=============================                                                                                                   | 23% ~8 s remaining     
|==============================                                                                                                  | 23% ~8 s remaining     
|==============================                                                                                                  | 24% ~8 s remaining     
|==============================                                                                                                  | 24% ~8 s remaining     
|==============================                                                                                                  | 24% ~8 s remaining     
|================================                                                                                                | 25% ~8 s remaining     
|================================                                                                                                | 26% ~8 s remaining     
|=================================                                                                                               | 26% ~8 s remaining     
|=================================                                                                                               | 26% ~8 s remaining     
|==================================                                                                                              | 27% ~8 s remaining     
|===================================                                                                                             | 28% ~8 s remaining     
|====================================                                                                                            | 29% ~8 s remaining     
|=====================================                                                                                           | 29% ~8 s remaining     
|=====================================                                                                                           | 29% ~8 s remaining     
|======================================                                                                                          | 30% ~8 s remaining     
|======================================                                                                                          | 30% ~8 s remaining     
|=======================================                                                                                         | 31% ~8 s remaining     
|=======================================                                                                                         | 31% ~8 s remaining     
|========================================                                                                                        | 32% ~7 s remaining     
|=========================================                                                                                       | 33% ~7 s remaining     
|==========================================                                                                                      | 33% ~7 s remaining     
|==========================================                                                                                      | 34% ~7 s remaining     
|===========================================                                                                                     | 34% ~7 s remaining     
|============================================                                                                                    | 35% ~7 s remaining     
|============================================                                                                                    | 35% ~7 s remaining     
|============================================                                                                                    | 35% ~8 s remaining     
|=============================================                                                                                   | 35% ~8 s remaining     
|=============================================                                                                                   | 35% ~8 s remaining     
|=============================================                                                                                   | 36% ~8 s remaining     
|==============================================                                                                                  | 36% ~8 s remaining     
|==============================================                                                                                  | 37% ~8 s remaining     
|===============================================                                                                                 | 37% ~8 s remaining     
|================================================                                                                                | 38% ~8 s remaining     
|================================================                                                                                | 38% ~8 s remaining     
|================================================                                                                                | 38% ~8 s remaining     
|=================================================                                                                               | 38% ~8 s remaining     
|=================================================                                                                               | 38% ~8 s remaining     
|=================================================                                                                               | 39% ~8 s remaining     
|=================================================                                                                               | 39% ~8 s remaining     
|==================================================                                                                              | 39% ~8 s remaining     
|===================================================                                                                             | 40% ~8 s remaining     
|====================================================                                                                            | 41% ~7 s remaining     
|====================================================                                                                            | 41% ~7 s remaining     
|====================================================                                                                            | 41% ~7 s remaining     
|=====================================================                                                                           | 42% ~7 s remaining     
|=====================================================                                                                           | 42% ~7 s remaining     
|=====================================================                                                                           | 42% ~8 s remaining     
|=====================================================                                                                           | 42% ~8 s remaining     
|=====================================================                                                                           | 42% ~8 s remaining     
|======================================================                                                                          | 42% ~8 s remaining     
|======================================================                                                                          | 43% ~8 s remaining     
|=======================================================                                                                         | 43% ~8 s remaining     
|=======================================================                                                                         | 43% ~8 s remaining     
|=======================================================                                                                         | 43% ~8 s remaining     
|=======================================================                                                                         | 44% ~8 s remaining     
|========================================================                                                                        | 44% ~8 s remaining     
|========================================================                                                                        | 45% ~8 s remaining     
|=========================================================                                                                       | 45% ~7 s remaining     
|==========================================================                                                                      | 46% ~7 s remaining     
|==========================================================                                                                      | 46% ~8 s remaining     
|==========================================================                                                                      | 46% ~8 s remaining     
|===========================================================                                                                     | 46% ~7 s remaining     
|===========================================================                                                                     | 47% ~7 s remaining     
|============================================================                                                                    | 47% ~7 s remaining     
|=============================================================                                                                   | 48% ~7 s remaining     
|=============================================================                                                                   | 48% ~7 s remaining     
|==============================================================                                                                  | 49% ~7 s remaining     
|===============================================================                                                                 | 49% ~7 s remaining     
|===============================================================                                                                 | 50% ~7 s remaining     
|================================================================                                                                | 50% ~7 s remaining     
|================================================================                                                                | 51% ~7 s remaining     
|=================================================================                                                               | 51% ~7 s remaining     
|=================================================================                                                               | 51% ~7 s remaining     
|==================================================================                                                              | 52% ~7 s remaining     
|===================================================================                                                             | 52% ~7 s remaining     
|===================================================================                                                             | 53% ~6 s remaining     
|====================================================================                                                            | 53% ~6 s remaining     
|====================================================================                                                            | 54% ~6 s remaining     
|=====================================================================                                                           | 54% ~6 s remaining     
|======================================================================                                                          | 55% ~6 s remaining     
|======================================================================                                                          | 55% ~6 s remaining     
|=======================================================================                                                         | 56% ~6 s remaining     
|=======================================================================                                                         | 56% ~6 s remaining     
|=======================================================================                                                         | 56% ~6 s remaining     
|========================================================================                                                        | 57% ~6 s remaining     
|========================================================================                                                        | 57% ~6 s remaining     
|=========================================================================                                                       | 58% ~6 s remaining     
|=========================================================================                                                       | 58% ~6 s remaining     
|==========================================================================                                                      | 58% ~6 s remaining     
|==========================================================================                                                      | 59% ~6 s remaining     
|===========================================================================                                                     | 59% ~6 s remaining     
|============================================================================                                                    | 60% ~6 s remaining     
|=============================================================================                                                   | 60% ~5 s remaining     
|==============================================================================                                                  | 61% ~5 s remaining     
|==============================================================================                                                  | 61% ~5 s remaining     
|==============================================================================                                                  | 62% ~5 s remaining     
|===============================================================================                                                 | 62% ~5 s remaining     
|================================================================================                                                | 63% ~5 s remaining     
|=================================================================================                                               | 63% ~5 s remaining     
|==================================================================================                                              | 64% ~5 s remaining     
|==================================================================================                                              | 65% ~5 s remaining     
|===================================================================================                                             | 65% ~5 s remaining     
|===================================================================================                                             | 66% ~5 s remaining     
|====================================================================================                                            | 66% ~5 s remaining     
|=====================================================================================                                           | 67% ~5 s remaining     
|=====================================================================================                                           | 67% ~5 s remaining     
|=====================================================================================                                           | 67% ~5 s remaining     
|======================================================================================                                          | 68% ~4 s remaining     
|=======================================================================================                                         | 68% ~4 s remaining     
|=======================================================================================                                         | 69% ~4 s remaining     
|=======================================================================================                                         | 69% ~4 s remaining     
|========================================================================================                                        | 69% ~4 s remaining     
|=========================================================================================                                       | 70% ~4 s remaining     
|===========================================================================================                                     | 71% ~4 s remaining     
|============================================================================================                                    | 72% ~4 s remaining     
|=============================================================================================                                   | 73% ~4 s remaining     
|===============================================================================================                                 | 74% ~3 s remaining     
|===============================================================================================                                 | 75% ~3 s remaining     
|================================================================================================                                | 76% ~3 s remaining     
|==================================================================================================                              | 77% ~3 s remaining     
|===================================================================================================                             | 77% ~3 s remaining     
|===================================================================================================                             | 78% ~3 s remaining     
|===================================================================================================                             | 78% ~3 s remaining     
|====================================================================================================                            | 78% ~3 s remaining     
|=====================================================================================================                           | 79% ~3 s remaining     
|=====================================================================================================                           | 79% ~3 s remaining     
|======================================================================================================                          | 80% ~3 s remaining     
|=======================================================================================================                         | 81% ~2 s remaining     
|========================================================================================================                        | 82% ~2 s remaining     
|==========================================================================================================                      | 83% ~2 s remaining     
|===========================================================================================================                     | 84% ~2 s remaining     
|===========================================================================================================                     | 84% ~2 s remaining     
|============================================================================================================                    | 85% ~2 s remaining     
|=============================================================================================================                   | 85% ~2 s remaining     
|==============================================================================================================                  | 86% ~2 s remaining     
|===============================================================================================================                 | 87% ~2 s remaining     
|================================================================================================================                | 88% ~2 s remaining     
|================================================================================================================                | 88% ~2 s remaining     
|================================================================================================================                | 88% ~2 s remaining     
|=================================================================================================================               | 88% ~2 s remaining     
|=================================================================================================================               | 89% ~1 s remaining     
|==================================================================================================================              | 89% ~1 s remaining     
|===================================================================================================================             | 90% ~1 s remaining     
|====================================================================================================================            | 91% ~1 s remaining     
|=====================================================================================================================           | 92% ~1 s remaining     
|=====================================================================================================================           | 92% ~1 s remaining     
|=====================================================================================================================           | 92% ~1 s remaining     
|======================================================================================================================          | 92% ~1 s remaining     
|======================================================================================================================          | 93% ~1 s remaining     
|=======================================================================================================================         | 93% ~1 s remaining     
|========================================================================================================================        | 94% ~1 s remaining     
|========================================================================================================================        | 94% ~1 s remaining     
|=========================================================================================================================       | 95% ~1 s remaining     
|==========================================================================================================================      | 96% ~1 s remaining     
|==========================================================================================================================      | 96% ~1 s remaining     
|==========================================================================================================================      | 96% ~1 s remaining     
|===========================================================================================================================     | 96% ~0 s remaining     
|============================================================================================================================    | 97% ~0 s remaining     
|============================================================================================================================    | 97% ~0 s remaining     
|============================================================================================================================    | 98% ~0 s remaining     
|==============================================================================================================================  | 98% ~0 s remaining     
|==============================================================================================================================  | 99% ~0 s remaining     
|=============================================================================================================================== | 99% ~0 s remaining     
vote_by_county_f <- left_join(vote_by_county_f, Demo_Factors, by='County')
candidate_order <- 'clinton' # CHANGE ME
level_order<-(filter(vote_by_county_f,variable == candidate_order) %>% 
                     select(County, proportion_numeric) %>% 
                     arrange(desc(proportion_numeric)))$County 
vote_by_county_f$County<- factor(vote_by_county_f$County, levels = level_order)
vote_by_county_f$variable<-factor(vote_by_county_f$variable, levels = c('other','stein','johnson','trump','clinton'))
# ggplot(filter(vote_by_county_f, !is.na(NCHS_UrbanRural2013)), aes(x=County, y=total_vote, fill=variable)) + 
#   geom_bar(stat='identity', position = 'fill') +
#   scale_fill_manual(values = c('clinton' = 'blue', 'trump' = 'red', 'stein' = 'green','johnson' = 'yellow','other' = 'purple'), 
#                     name = 'Candidate',
#                     breaks = c('other','stein','johnson','trump','clinton'),
#                     labels = c('Others','Jill Stein','Gary Johnson','Donald J Trump','Hillary Clinton')) +
#   labs(x = NULL, y = 'Percent of Vote')+
#   scale_y_continuous(labels = scales::percent) +
#   ggtitle('Percent of Vote by County', subtitle='2016 USA Presidential Election') +
#   theme(axis.text.x = element_blank(), axis.ticks.x = element_blank()) +
#   facet_wrap(~NCHS_UrbanRural2013, scales = 'free_x')
facetting_variable <- 'MedianAge' #Change Me
vote_by_county_f$fct <- cut(vote_by_county_f[[facetting_variable]], 
                            breaks = c(0,quantile(vote_by_county_f[[facetting_variable]], 
                                              probs = c(0.1, 0.25, 0.5, 0.75, 0.9),
                                              na.rm = T),Inf),
                            ordered_result = T,
                            labels = c('Lowest 10%','10th - 25th %ile',
                                       '25th %ile - Median','Median - 75th %ile',
                                       '75th - 90th %ile', 'Top 10%'))
ggplot(filter(vote_by_county_f, !is.na(fct)), aes(x=County, y=total_vote, fill=variable)) + 
  geom_bar(stat='identity', position = 'fill') +
  scale_fill_manual(values = c('clinton' = 'blue', 'trump' = 'red', 'stein' = 'green','johnson' = 'yellow','other' = 'purple'), 
                    name = 'Candidate',
                    breaks = c('other','stein','johnson','trump','clinton'),
                    labels = c('Others','Jill Stein','Gary Johnson','Donald J Trump','Hillary Clinton')) +
  labs(x = NULL, y = 'Percent of Vote')+
  scale_y_continuous(labels = scales::percent) +
  ggtitle(paste0('Percent of Vote by County ~ ',facetting_variable), subtitle='2016 USA Presidential Election') +
  theme(axis.text.x = element_blank(), axis.ticks.x = element_blank()) +
  facet_wrap(~fct, scales = 'free_x')

  • Let’s try different ways of facetting.
    • Here we are looking at the impact of different variables on their vote for Trump. I’ve also included a df for individual r-squared values, here.
states_by_region <- read_csv('./states_by_region.csv')
data2016 <- left_join(data2016, select(states_by_region, -`State Code`), by = c('StateName'='State'))
Demo_Factors <- mutate(data2016, MfgEmpChange1980_2015 = (MfgEmp2015/TotalEmp2015) - (MfgEmp1980/TotalEmp1980)) %>% 
  select(County, rDRPct, Region, MfgEmpChange1980_2015, NCHS_UrbanRural2013, TotalPopulation, MedianAge, MedianHouseholdIncome, SimpsonDiversityIndex, propWhite, propBlack, propMfg2015, propHS, propMoreHS, propUnemp, propElders, propNMarried)
Demo_Factors$Region<- as.factor(Demo_Factors$Region)
Demo_Factors_m <- melt(select(Demo_Factors, -NCHS_UrbanRural2013), id = c('County','rDRPct'))
r_squareds <- data_frame(variable = unique(Demo_Factors_m$variable))
r_squareds$r_square <- sapply(r_squareds$variable, function(i){
  percent_format()(summary(lm(unlist(Demo_Factors[as.character(i)])~Demo_Factors$rDRPct))$r.squared)
})
Demo_Factors_m <- left_join(Demo_Factors_m, r_squareds, by='variable')
ggplot(Demo_Factors_m, aes(x=value, y=rDRPct)) +
  geom_point() +
  geom_smooth(method = 'lm') +
  facet_wrap(~variable, scales = 'free_x')

Manufacturing Visualization

# pulled from https://github.com/cphalpert/census-regions/blob/master/us%20census%20bureau%20regions%20and%20divisions.csv
states_by_region <- read_csv('./states_by_region.csv')
data2016 <- left_join(data2016, select(states_by_region, -`State Code`), by = c('StateName'='State'))
Demo_Factors <- mutate(data2016, MfgEmpChange1980_2015 = (MfgEmp2015/TotalEmp2015) - (MfgEmp1980/TotalEmp1980),
                       region_division = paste(Region,'-',Division)) %>%
  select(County, rDRPct, Region, region_division, MfgEmpChange1980_2015, NCHS_UrbanRural2013, TotalPopulation, MedianAge,
         MedianHouseholdIncome, SimpsonDiversityIndex, propWhite, propBlack, propMfg2015, propHS, propMoreHS, propUnemp,
         propElders, propNMarried)
Demo_Factors$Region<- as.factor(Demo_Factors$Region)
Demo_Factors$region_division <- as.factor(Demo_Factors$region_division)
Demo_Factors_m2 <- melt(select(Demo_Factors, County, rDRPct, MfgEmpChange1980_2015, propWhite, region_division), 
                        id = c('County','rDRPct','MfgEmpChange1980_2015'))
regional_mfg<-filter(Demo_Factors_m2, variable == 'region_division', !is.na(MfgEmpChange1980_2015)) %>% select(-variable)
ggplot(regional_mfg, aes(x=MfgEmpChange1980_2015, y=rDRPct))+
  geom_point()+
  geom_smooth(method = 'lm')+
  facet_wrap(~value)

ggplot(regional_mfg, aes(x=value, y=MfgEmpChange1980_2015)) + 
  geom_boxplot()+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Demo_Factors<-left_join(Demo_Factors, mutate(data2016, BlindDisabledSSI_p = BlindDisabledSSI / TotalPopulation) 
                        %>% select(County, BlindDisabledSSI_p))

Models

summary(lm(rDRPct ~  Region + propWhite + NCHS_UrbanRural2013 + propNMarried, Demo_Factors))

Call:
lm(formula = rDRPct ~ Region + propWhite + NCHS_UrbanRural2013 + 
    propNMarried, data = Demo_Factors)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.59819 -0.05725  0.01011  0.06696  0.37174 

Coefficients:
                                                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)                                        0.440370   0.026992  16.315  < 2e-16 ***
RegionNortheast                                   -0.066455   0.007889  -8.424  < 2e-16 ***
RegionSouth                                        0.063649   0.004628  13.752  < 2e-16 ***
RegionWest                                        -0.024467   0.005854  -4.180 3.00e-05 ***
propWhite                                          0.373048   0.016642  22.416  < 2e-16 ***
NCHS_UrbanRural2013Large fringe metro              0.082674   0.013900   5.948 3.02e-09 ***
NCHS_UrbanRural2013Medium metro                    0.096519   0.013858   6.965 3.99e-12 ***
NCHS_UrbanRural2013Micropolitan (nonmetropolitan)  0.141172   0.013474  10.477  < 2e-16 ***
NCHS_UrbanRural2013Noncore (nonmetropolitan)       0.160562   0.013363  12.016  < 2e-16 ***
NCHS_UrbanRural2013Small metro                     0.129140   0.013907   9.286  < 2e-16 ***
propNMarried                                      -0.906555   0.038321 -23.657  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1023 on 3128 degrees of freedom
  (2 observations deleted due to missingness)
Multiple R-squared:  0.6021,    Adjusted R-squared:  0.6008 
F-statistic: 473.3 on 10 and 3128 DF,  p-value: < 2.2e-16

Manufacturing Decline

  • Where? Within region?

BLS Data

  • I pulled in labor force data from BLS, and joined it to our dataset.
  • The number of discouraged workers by county was not available, so I tried to back into the number.
    • There are significant problems with the way I did this, because it doesn’t account for school or disability or anything else.
  • It turns out it’s not very explanatory.
summary(lm(rDRPct ~  BlindDisabledSSI_p + propDiscouraged + MfgEmpChange1980_2015, Demo_Factors))

Call:
lm(formula = rDRPct ~ BlindDisabledSSI_p + propDiscouraged + 
    MfgEmpChange1980_2015, data = Demo_Factors)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.59099 -0.08812  0.02904  0.11475  0.32123 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)            0.661338   0.006841  96.679  < 2e-16 ***
BlindDisabledSSI_p    -1.027191   0.253088  -4.059 5.09e-05 ***
propDiscouraged        0.241958   0.056277   4.299 1.78e-05 ***
MfgEmpChange1980_2015  0.147426   0.036760   4.010 6.25e-05 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1537 on 2396 degrees of freedom
  (741 observations deleted due to missingness)
Multiple R-squared:  0.01473,   Adjusted R-squared:  0.0135 
F-statistic: 11.94 on 3 and 2396 DF,  p-value: 9.228e-08
LS0tDQp0aXRsZTogIlZpc3VhbGl6aW5nIGFuZCBNb2RlbGluZyAyMDE2IFVTIFByZXNpZGVudGlhbCBFbGVjdGlvbiBSZXN1bHRzIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiAnNCcNCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0aGVtZTogeWV0aQ0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB5ZXMNCi0tLQ0KVGhpcyBkYXRhIHNldHVwIHN0b2xlbiBicmF6ZW5seSBmcm9tIEplbm5pZmVyIFRob21wc29uLg0KYGBge3Igc2V0dXB9DQprbml0cjo6b3B0c19jaHVuayRzZXQobWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UpDQoNCiMjIExvYWQgbGlicmFyaWVzIHdlJ2xsIHVzZQ0KIyBsaWJyYXJ5KGRldnRvb2xzKQ0KIyBpbnN0YWxsX2dpdGh1YignZGF0YWRvdHdvcmxkL2RhdGEud29ybGQtcicpDQpsaWJyYXJ5KGRhdGEud29ybGQpICMjIGZvciBxdWVyeWluZyBkaXJlY3RseSBmcm9tIGRhdGEud29ybGQNCmxpYnJhcnkodGlkeXZlcnNlKSAgIyMgZm9yIGRhdGEgd3JhbmdsaW5nIGFuZCBwaXBpbmcNCmxpYnJhcnkocm1zKSAgICAgICAgIyMgcm1zIGhhcyBuaWNlIGZ1bmN0aW9uYWxpdHkgZm9yIGdldHRpbmcgcHJlZGljdGVkIHZhbHVlcyBmcm9tIG1vZGVsIG9iamVjdHMNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeShyZXNoYXBlMikgICAjIyBJIGtub3cgdGhpcyBiZXR0ZXIgdGhhbiB0aWR5ciAtQHJrYWhuZQ0KDQpzdGF0ZV9uYW1lcyA9IGMoDQonQWxhYmFtYScgPSAwMUwsDQonQWxhc2thJyA9IDAyTCwNCidBcml6b25hJyA9IDA0TCwNCidBcmthbnNhcycgPSAwNUwsDQonQ2FsaWZvcm5pYScgPSAwNkwsDQonQ29sb3JhZG8nID0gMDhMLA0KJ0Nvbm5lY3RpY3V0JyA9IDA5TCwNCidEZWxhd2FyZScgPSAxMEwsDQonRmxvcmlkYScgPSAxMkwsDQonR2VvcmdpYScgPSAxM0wsDQonSGF3YWlpJyA9IDE1TCwNCidJZGFobycgPSAxNkwsDQonSWxsaW5vaXMnID0gMTdMLA0KJ0luZGlhbmEnID0gMThMLA0KJ0lvd2EnID0gMTlMLA0KJ0thbnNhcycgPSAyMEwsDQonS2VudHVja3knID0gMjFMLA0KJ0xvdWlzaWFuYScgPSAyMkwsDQonTWFpbmUnID0gMjNMLA0KJ01hcnlsYW5kJyA9IDI0TCwNCidNYXNzYWNodXNldHRzJyA9IDI1TCwNCidNaWNoaWdhbicgPSAyNkwsDQonTWlubmVzb3RhJyA9IDI3TCwNCidNaXNzaXNzaXBwaScgPSAyOEwsDQonTWlzc291cmknID0gMjlMLA0KJ01vbnRhbmEnID0gMzBMLA0KJ05lYnJhc2thJyA9IDMxTCwNCidOZXZhZGEnID0gMzJMLA0KJ05ldyBIYW1wc2hpcmUnID0gMzNMLA0KJ05ldyBKZXJzZXknID0gMzRMLA0KJ05ldyBNZXhpY28nID0gMzVMLA0KJ05ldyBZb3JrJyA9IDM2TCwNCidOb3J0aCBDYXJvbGluYScgPSAzN0wsDQonTm9ydGggRGFrb3RhJyA9IDM4TCwNCidPaGlvJyA9IDM5TCwNCidPa2xhaG9tYScgPSA0MEwsDQonT3JlZ29uJyA9IDQxTCwNCidQZW5uc3lsdmFuaWEnID0gNDJMLA0KJ1Job2RlIElzbGFuZCcgPSA0NEwsDQonU291dGggQ2Fyb2xpbmEnID0gNDVMLA0KJ1NvdXRoIERha290YScgPSA0NkwsDQonVGVubmVzc2VlJyA9IDQ3TCwNCidUZXhhcycgPSA0OEwsDQonVXRhaCcgPSA0OUwsDQonVmVybW9udCcgPSA1MEwsDQonVmlyZ2luaWEnID0gNTFMLA0KJ1dhc2hpbmd0b24nID0gNTNMLA0KJ1dlc3QgVmlyZ2luaWEnID0gNTRMLA0KJ1dpc2NvbnNpbicgPSA1NUwsDQonV3lvbWluZycgPSA1NkwsDQonRGlzdHJpY3Qgb2YgQ29sdW1iaWEnID0gMTFMDQopDQoNCmVsZWN0b3JhbF92b3RlcyA9IGMoDQonQWxhYmFtYScgPSA5LA0KJ0FsYXNrYScgPSAzTCwNCidBcml6b25hJyA9IDExLA0KJ0Fya2Fuc2FzJyA9IDYsDQonQ2FsaWZvcm5pYScgPSA1NUwsDQonQ29sb3JhZG8nID0gOSwNCidDb25uZWN0aWN1dCcgPSA3LA0KJ0RlbGF3YXJlJyA9IDMsDQonRmxvcmlkYScgPSAyOSwNCidHZW9yZ2lhJyA9IDE2LA0KJ0hhd2FpaScgPSA0LA0KJ0lkYWhvJyA9IDQsDQonSWxsaW5vaXMnID0gMjAsDQonSW5kaWFuYScgPSAxMSwNCidJb3dhJyA9IDYsDQonS2Fuc2FzJyA9IDYsDQonS2VudHVja3knID0gOCwNCidMb3Vpc2lhbmEnID0gOCwNCidNYWluZScgPSA0LA0KJ01hcnlsYW5kJyA9IDEwLA0KJ01hc3NhY2h1c2V0dHMnID0gMTEsDQonTWljaGlnYW4nID0gMTYsDQonTWlubmVzb3RhJyA9IDEwLA0KJ01pc3Npc3NpcHBpJyA9IDYsDQonTWlzc291cmknID0gMTAsDQonTW9udGFuYScgPSAzLA0KJ05lYnJhc2thJyA9IDUsDQonTmV2YWRhJyA9IDYsDQonTmV3IEhhbXBzaGlyZScgPSA0LA0KJ05ldyBKZXJzZXknID0gMTQsDQonTmV3IE1leGljbycgPSA1LA0KJ05ldyBZb3JrJyA9IDI5LA0KJ05vcnRoIENhcm9saW5hJyA9IDE1LA0KJ05vcnRoIERha290YScgPSAzLA0KJ09oaW8nID0gMTgsDQonT2tsYWhvbWEnID0gNywNCidPcmVnb24nID0gNywNCidQZW5uc3lsdmFuaWEnID0gMjAsDQonUmhvZGUgSXNsYW5kJyA9IDQsDQonU291dGggQ2Fyb2xpbmEnID0gOSwNCidTb3V0aCBEYWtvdGEnID0gMywNCidUZW5uZXNzZWUnID0gMTEsDQonVGV4YXMnID0gMzgsDQonVXRhaCcgPSA2LA0KJ1Zlcm1vbnQnID0gMywNCidWaXJnaW5pYScgPSAxMywNCidXYXNoaW5ndG9uJyA9IDEyLA0KJ1dlc3QgVmlyZ2luaWEnID0gNSwNCidXaXNjb25zaW4nID0gMTAsDQonV3lvbWluZycgPSAzLA0KJ0Rpc3RyaWN0IG9mIENvbHVtYmlhJyA9IDMNCikNCg0KZWxlY3Rpb25zIDwtbGlzdCgNCiAgJ0VsZWN0aW9uXzIwMDAnID0gcmVhZF9jc3YoJ2h0dHBzOi8vcXVlcnkuZGF0YS53b3JsZC9zLzQwNGFxMHU0bjk4aG1venVnaHAwOG5wZzEnKSAlPiUgc2VsZWN0KENvdW50eSwgQ291bnR5TmFtZSwgU3RhdGVOYW1lLCBidXNoLCBnb3JlLCBuYWRlciwgYnJvd25lLCBvdGhlciksDQogICdFbGVjdGlvbl8yMDA0JyA9IHJlYWRfY3N2KCdodHRwczovL3F1ZXJ5LmRhdGEud29ybGQvcy82bXI5Mnc0cDkycmVtNGJwYnMxZ2d6Y3VpJykgJT4lIHNlbGVjdChDb3VudHksIENvdW50eU5hbWUsIFN0YXRlTmFtZSwgYnVzaCwga2VycnksIG90aGVyKSwNCiAgJ0VsZWN0aW9uXzIwMDgnID0gcmVhZF9jc3YoJ2h0dHBzOi8vcXVlcnkuZGF0YS53b3JsZC9zLzhwejY0eTVwZ2x2OGR0NnVteXNmZmdhaGgnKSAlPiUgc2VsZWN0KENvdW50eSwgQ291bnR5TmFtZSwgU3RhdGVOYW1lLCBtY2NhaW4sIG9iYW1hLCBvdGhlciksDQogICdFbGVjdGlvbl8yMDEyJyA9IHJlYWRfY3N2KCdodHRwczovL3F1ZXJ5LmRhdGEud29ybGQvcy8yOXNlZDAxd2tiOWxqbWdnMGtnajN6dG9wJykgJT4lIHNlbGVjdChDb3VudHksIENvdW50eU5hbWUsIFN0YXRlTmFtZSwgcm9tbmV5LCBvYmFtYSwgam9obnNvbiwgc3RlaW4sIG90aGVyKSwNCiAgJ0VsZWN0aW9uXzIwMTYnID0gcmVhZF9jc3YoJ2h0dHBzOi8vcXVlcnkuZGF0YS53b3JsZC9zL2RtamNhcGVuaDRmZzh5N2NobDVvcWdqdG8nKSAlPiUgc2VsZWN0KENvdW50eSwgQ291bnR5TmFtZSwgU3RhdGVOYW1lLCB0cnVtcCwgY2xpbnRvbiwgam9obnNvbiwgc3RlaW4sIG90aGVyKQ0KKQ0KZWxlY3Rpb25zW1sxXV0kQ291bnR5IDwtIGFzLmludGVnZXIoZWxlY3Rpb25zW1sxXV0kQ291bnR5KQ0KDQpgYGANCg0KV2Ugd2FudCB0byBkZXRlcm1pbmUgd2hhdCBjb3VudHkgY2hhcmFjdGVyaXN0aWNzIG1heSBiZSBwcmVkaWN0b3JzIG9mIGJvdGggdGhlIGNvdW50eSdzIGZpbmFsIHdpbm5lcg0KaW4gdGhlIDIwMTYgcHJlc2lkZW50aWFsIGVsZWN0aW9uLCBhbmQgdGhlIG1hcmdpbiBvZiB2aWN0b3J5IGJ5IHdoaWNoIHRoYXQgY2FuZGlkYXRlIHdvbi4NCg0KIyBQcm9qZWN0IFNldHVwDQoNCiMjIExvYWRpbmcgRGF0YQ0KDQpXZSdsbCBsb2FkIHRoZSBjb3VudHkgY2hhcmFjdGVyaXN0aWNzIGFuZCAyMDE2IHByZXNpZGVudGlhbCBlbGVjdGlvbiByZXN1bHRzIGRhdGFzZXRzIGRpcmVjdGx5IGZyb20gZGF0YS53b3JsZC4NCg0KIyMjIENvdW50eSBDaGFyYWN0ZXJpc3RpY3MNCg0KVGhlc2UgZGF0YSBhcmUgbW9zdGx5IGZyb20gdGhlIDIwMTUgW0FtZXJpY2FuIENvbW11bml0eSBTdXJ2ZXldKGh0dHBzOi8vd3d3LmNlbnN1cy5nb3YvcHJvZ3JhbXMtc3VydmV5cy9hY3MvKSwgd2l0aCBhZGRpdGlvbmFsIGRhdGEgZnJvbSBvdGhlciBzb3VyY2VzLiBBDQpmdWxsIGRhdGEgZGljdGlvbmFyeSBjYW4gYmUgZm91bmQgW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9EYXRhNERlbW9jcmFjeS9lbGVjdGlvbi10cmFuc3BhcmVuY3kvYmxvYi9tYXN0ZXIvZGF0YS1kaWN0aW9uYXJ5L2NvdW50eS1sZXZlbC9Db3VudHlDaGFyYWN0ZXJpc3RpY3MubWQpLg0KDQpgYGB7ciBsb2FkX2NvdW50eV9kYXRhfQ0KbGlicmFyeShkYXRhLndvcmxkKQ0KDQojIyBTZXQgY29ubmVjdGlvbiAoc2VlIHBhY2thZ2UgUkVBRE1FIGZvciBkZXRhaWxzOiBodHRwczovL2dpdGh1Yi5jb20vZGF0YWRvdHdvcmxkL2RhdGEud29ybGQtcikNCmNvbm48LWRhdGEud29ybGQocmVhZF9jc3YoJ0M6L1VzZXJzL3JrYWhuZS9Eb2N1bWVudHMvZGF0YV93b3JsZF9hcGkuY3N2Jykka2V5KQ0KDQojICMjIFdoYXQgZGF0YSB0YWJsZXMgYXJlIGF2YWlsYWJsZT8gKGJvdGggZHBseXIgYW5kIGRhdGEud29ybGQgaGF2ZSBhIHF1ZXJ5KCk7IG11c3Qgc3BlY2lmeSkNCiMgZGF0YV9saXN0IDwtIGRhdGEud29ybGQ6OnF1ZXJ5KGNvbm4sDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhc2V0ID0gJ2RhdGE0ZGVtb2NyYWN5L2VsZWN0aW9uLXRyYW5zcGFyZW5jeScsDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWVyeSA9ICJTRUxFQ1QgKiBGUk9NIFRhYmxlcyIpDQojIGRhdGFfbGlzdA0KDQpjb3VudHlDaGFyIDwtIGRhdGEud29ybGQ6OnF1ZXJ5KGNvbm4sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFzZXQgPSAnZGF0YTRkZW1vY3JhY3kvZWxlY3Rpb24tdHJhbnNwYXJlbmN5JywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVlcnkgPSAiU0VMRUNUICogRlJPTSBDb3VudHlDaGFyYWN0ZXJpc3RpY3MiKQ0KDQpgYGANCg0KIyMjIFZvdGVyIFJlZ2lzdHJhdGlvbg0KDQpXZSBhbHNvIHdhbnQgcGFydHkgcmVnaXN0cmF0aW9uIGRhdGEgZnJvbSBOb3ZlbWJlciAyMDE2LCBxdWVyaWVkIGZyb20gdGhlIGZ1bGwgYFBhcnR5UmVnaXN0cmF0aW9uYA0KZmlsZS4gVGhpcyBmaWxlIGluY2x1ZGVzIGRhdGEgcHVsbGVkIGZyb20gZWFjaCBzdGF0ZSdzIFNlY3JldGFyeSBvZiBTdGF0ZSB3ZWIgc2l0ZS4gRnVsbCBkYXRhDQpkaWN0aW9uYXJ5IGlzIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vRGF0YTREZW1vY3JhY3kvZWxlY3Rpb24tdHJhbnNwYXJlbmN5L2Jsb2IvbWFzdGVyL2RhdGEtZGljdGlvbmFyeS9jb3VudHktbGV2ZWwvUGFydHlSZWdpc3RyYXRpb24ubWQpLg0KDQpTb21lIG9mIHRoZSB2YXJpYWJsZSBuYW1lcyBvdmVybGFwIHdpdGggbmFtZXMgaW4gdGhlIG5leHQgZGF0YXNldDsgd2UnbGwgZHJvcCB2YXJpYWJsZXMgdGhhdCBhcmUNCnJlZHVuZGFudCAoc3RhdGUvY291bnR5IG5hbWVzL2FiYnJldmlhdGlvbnMgYW5kIHllYXIvbW9udGggb2YgcmVnaXN0cmF0aW9uKSBhbmQgYWRkICJSZWciIHRvDQpldmVyeXRoaW5nIGVsc2UgZXhjZXB0IHN0YXRlL2NvdW50eSBrZXlzIHRvIGNsYXJpZnkgdGhhdCBpdCdzIHJlZ2lzdHJhdGlvbiBpbmZvLg0KDQpgYGB7ciBsb2FkX3JlZ2lzdHJhdGlvbl9kYXRhfQ0Kdm90ZXJSZWcyMDE2IDwtDQogIGRhdGEud29ybGQ6OnF1ZXJ5KGNvbm4sDQogICAgICAgICAgICAgICAgICAgIGRhdGFzZXQgPSAnZGF0YTRkZW1vY3JhY3kvZWxlY3Rpb24tdHJhbnNwYXJlbmN5JywNCiAgICAgICAgICAgICAgICAgICAgcXVlcnkgPSAiU0VMRUNUICogRlJPTSBQYXJ0eVJlZ2lzdHJhdGlvbiBXSEVSRSBZZWFyID0gMjAxNiBBTkQgTW9udGggPSAxMSIpDQoNCnZvdGVyUmVnMjAxNiA8LSB2b3RlclJlZzIwMTYgJT4lDQogIHNlbGVjdCgtb25lX29mKCJDb3VudHlOYW1lIiwgIlN0YXRlTmFtZSIsICJTdGF0ZUFiYnIiLCAiWWVhciIsICJNb250aCIsICJZZWFyTW9udGgiKSkNCg0KbmFtZXModm90ZXJSZWcyMDE2KSA8LSBpZmVsc2UobmFtZXModm90ZXJSZWcyMDE2KSAlaW4lIGMoJ1N0YXRlJywgJ0NvdW50eScpLCBuYW1lcyh2b3RlclJlZzIwMTYpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKG5hbWVzKHZvdGVyUmVnMjAxNiksICdSZWcnKSkNCg0KYGBgDQoNCiMjIyBQcmVzaWRlbnRpYWwgRWxlY3Rpb24gUmVzdWx0cyBieSBDb3VudHkNCg0KVGhlc2UgZGF0YSBhcmUgY29sbGVjdGVkIGZyb20gYSBIYXJ2YXJkIHJlc2VhcmNoIHByb2plY3QuIEEgZnVsbCBkYXRhIGRpY3Rpb25hcnkgY2FuIGJlIGZvdW5kIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vRGF0YTREZW1vY3JhY3kvZWxlY3Rpb24tdHJhbnNwYXJlbmN5L2Jsb2IvbWFzdGVyL2RhdGEtZGljdGlvbmFyeS9jb3VudHktbGV2ZWwvUHJlc2lkZW50aWFsRWxlY3Rpb25SZXN1bHRzMjAxNi5tZCkuDQoNCmBgYHtyIGxvYWRfcmVzdWx0c19kYXRhfQ0KcHJlc1Jlc3VsdHMyMDE2IDwtIGRhdGEud29ybGQ6OnF1ZXJ5KGNvbm4sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YXNldCA9ICdkYXRhNGRlbW9jcmFjeS9lbGVjdGlvbi10cmFuc3BhcmVuY3knLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXJ5ID0gIlNFTEVDVCAqIEZST00gUHJlc2lkZW50aWFsRWxlY3Rpb25SZXN1bHRzMjAxNiIpDQoNCmBgYA0KDQojIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzDQoNCkxldCdzIGpvaW4gdGhlIGRhdGFzZXRzLCBjYWxjdWxhdGUgc29tZSBwcm9wb3J0aW9ucywgYW5kIGxvb2sgYXQgc29tZSBiYXNpYyBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzLg0KDQpgYGB7ciBqb2luX2RhdGF9DQojIyBDaGVjayB3aGF0IHZhcmlhYmxlcyBhcmUgaW4gY29tbW9uDQojIGludGVyc2VjdChuYW1lcyhjb3VudHlDaGFyKSwgbmFtZXModm90ZXJSZWcyMDE2KSkNCiMgaW50ZXJzZWN0KG5hbWVzKGNvdW50eUNoYXIpLCBuYW1lcyhwcmVzUmVzdWx0czIwMTYpKQ0KDQpkYXRhMjAxNiA8LSByZWR1Y2UobGlzdChjb3VudHlDaGFyLCB2b3RlclJlZzIwMTYsIHByZXNSZXN1bHRzMjAxNiksDQogICAgICAgICAgICAgICAgICAgbGVmdF9qb2luLA0KICAgICAgICAgICAgICAgICAgIGJ5ID0gYygnQ291bnR5JywgJ1N0YXRlJykpDQoNCiMjIEZ1bmN0aW9uIHRvIHF1aWNrbHkgY2FsY3VsYXRlIGEgcHJvcG9ydGlvbiBvdXQgb2YgVG90YWxQb3B1bGF0aW9uIC0gd2UnbGwgbmVlZCB0byBkbyB0aGlzIGEgbG90DQpwcm9wX3RvdGFsIDwtIGZ1bmN0aW9uKHgpeyB4IC8gZGF0YTIwMTYkVG90YWxQb3B1bGF0aW9uIH0NCg0KZGF0YTIwMTYgPC0gZGF0YTIwMTYgJT4lDQogICMjIENhbGN1bGF0ZSBsb3RzIG9mIHByb3BvcnRpb24gdmFyaWFibGVzDQogIG11dGF0ZShwcm9wTWFsZSA9IHByb3BfdG90YWwoTWFsZSksDQogICAgICAgICBwcm9wS2lkcyA9IHByb3BfdG90YWwoQWdlMF80ICsgQWdlNV85ICsgQWdlMTBfMTQgKyBBZ2UxNV8xOSksDQogICAgICAgICBwcm9wQWR1bHRzTm9UZWVucyA9IDEgLSBwcm9wS2lkcywNCiAgICAgICAgICMjIDE1LTE5IGlzIGluY2x1ZGVkIGluIGxhYm9yIGZvcmNlLCBtYXJpdGFsIHN0YXR1cyBxdWVzdGlvbnMNCiAgICAgICAgIHRvdGFsQWR1bHRzV2l0aFRlZW5zID0gQWdlMTVfMTkgKyBBZ2UyMF8yNCArIEFnZTI1XzM0ICsgQWdlMzVfNDQgKyBBZ2U0NV81NCArIEFnZTU1XzU5ICsNCiAgICAgICAgICAgQWdlNjBfNjQgKyBBZ2U2NV83NCArIEFnZTc1Xzg0ICsgQWdlODUsDQogICAgICAgICBwcm9wQWR1bHRzV2l0aFRlZW5zID0gcHJvcF90b3RhbCh0b3RhbEFkdWx0c1dpdGhUZWVucyksDQogICAgICAgICAjIyBPbmx5ID4xOCBpbmNsdWRlZCBpbiBlZHVjYXRpb24gcXVlc3Rpb25zDQogICAgICAgICB0b3RhbEFkdWx0c05vVGVlbnMgPSBBZ2UyMF8yNCArIEFnZTI1XzM0ICsgQWdlMzVfNDQgKyBBZ2U0NV81NCArIEFnZTU1XzU5ICsgQWdlNjBfNjQgKw0KICAgICAgICAgICBBZ2U2NV83NCArIEFnZTc1Xzg0ICsgQWdlODUsDQogICAgICAgICBwcm9wRWxkZXJzID0gcHJvcF90b3RhbChBZ2U2NV83NCArIEFnZTc1Xzg0ICsgQWdlODUpLA0KICAgICAgICAgcHJvcE5NYXJyaWVkID0gTmV2ZXJNYXJyaWVkIC8gdG90YWxBZHVsdHNXaXRoVGVlbnMsDQogICAgICAgICBwcm9wSGlzcGFuaWMgPSBwcm9wX3RvdGFsKEhpc3BhbmljKSwNCiAgICAgICAgIHByb3BXaGl0ZSA9IHByb3BfdG90YWwoV2hpdGUpLA0KICAgICAgICAgcHJvcEJsYWNrID0gcHJvcF90b3RhbChCbGFjayksDQogICAgICAgICBtYWpXaGl0ZSA9IHByb3BXaGl0ZSA+IDAuNSwNCiAgICAgICAgIG1hakJsYWNrID0gcHJvcEJsYWNrID4gMC41LA0KICAgICAgICAgcHJvcE5vSFMgPSAoRWRLOCArIEVkOV8xMikgLyB0b3RhbEFkdWx0c05vVGVlbnMsDQogICAgICAgICBwcm9wSFMgPSBFZEhTIC8gdG90YWxBZHVsdHNOb1RlZW5zLA0KICAgICAgICAgcHJvcE1vcmVIUyA9IChFZENvbGxOb0RlZ3JlZSArIEVkQXNzb2NEZWdyZWUgKyBFZEJhY2hlbG9yRGVncmVlICsgRWRHcmFkdWF0ZURlZ3JlZSkgLw0KICAgICAgICAgICB0b3RhbEFkdWx0c05vVGVlbnMsDQogICAgICAgICBwcm9wTWZnMjAxNSA9IE1mZ0VtcDIwMTUgLyBMYWJvckZvcmNlLA0KICAgICAgICAgcHJvcFVuZW1wID0gVW5lbXBsb3ltZW50IC8gTGFib3JGb3JjZSwNCiAgICAgICAgIHByb3BMYWJvckZvcmNlID0gcHJvcF90b3RhbChMYWJvckZvcmNlKSwNCiAgICAgICAgIHByb3BTdGVpbiA9IHN0ZWluIC8gdG90YWx2b3RlcywNCiAgICAgICAgIHByb3BKb2huc29uID0gam9obnNvbiAvIHRvdGFsdm90ZXMsDQogICAgICAgICBwcm9wVHJ1bXAgPSB0cnVtcCAvIHRvdGFsdm90ZXMsDQogICAgICAgICBwcm9wQ2xpbnRvbiA9IGNsaW50b24gLyB0b3RhbHZvdGVzLA0KICAgICAgICAgcHJvcFZvdGVycyA9IHRvdGFsdm90ZXMgLyB0b3RhbEFkdWx0c05vVGVlbnMsDQogICAgICAgICB2b3RlZFRydW1wID0gclBjdCA+IDAuNSwNCiAgICAgICAgIHN0YXRlX0VWID0gZWxlY3RvcmFsX3ZvdGVzW1N0YXRlTmFtZV0pDQojIyBWaWV3IGZ1bGwgZGF0YSBmcmFtZQ0KZGF0YTIwMTYNCg0KYGBgDQojIyBWaXN1YWxpemF0aW9ucyENCiogSSBtYWRlIHNvbWUgc21hbGwgbW9kaWZpY2F0aW9ucyB0byB0aGUgY29kZSBhYm92ZSwgbXkgbW9kZmljaWF0aW9ucyBtb3N0bHkgdHVybmVkIG91dCB0byBiZSB1c2VsZXNzLCBhbnl3YXkuDQoqIEkgKHJrYWhuZSkgcmVhbGx5IHN0YXJ0ZWQgZG9pbmcgd29yayBhcm91bmQgaGVyZS4NCiogVGhlIGdvYWwgKGZvciBtZSwgcmlnaHQgbm93KSBpcyB0byBidWlsZCBvdXQgZGF0YWZyYW1lcyBmcm9tIHRoZSBncmVhdCB3b3JrIGRvbmUgYnkgSmVubmlmZXIgVGhvbXBzb24gdGhhdCBjYW4gYmUgdXNlZCB3aXRoIGdncGxvdC4NCiogSSd2ZSBkb25lIHNvbWUgVmVyeSBCYXNpYyBCYXJwbG90cyB0byBnZXQgc3RhcnRlZC4gIEkgaG9wZSBvdGhlciBwZW9wbGUgY2FuIHRha2UgdGhpcyBzdHVmZiwgbW9kaWZ5IGl0LCBhbmQgZmluZCBzb21lIGNvb2wgYW5kIGludGVyZXN0aW5nIHN0dWZmIGluIGhlcmUuDQoNCiMjI0NhbmRpZGF0ZSB2b3RlIHRvdGFscyBieSBTdGF0ZQ0KYGBge3J9DQp2b3RlX2J5X3N0YXRlPC1zZWxlY3QoZGF0YTIwMTYsIFN0YXRlTmFtZSwgc3RhdGVfRVYsIGNsaW50b24sIHRydW1wLCBqb2huc29uLCBzdGVpbiwgb3RoZXIpICU+JSANCiAgbWVsdChpZD0gYygnU3RhdGVOYW1lJywnc3RhdGVfRVYnKSkgJT4lIA0KICBncm91cF9ieShTdGF0ZU5hbWUsIHN0YXRlX0VWLCB2YXJpYWJsZSkgJT4lIA0KICBkcGx5cjo6c3VtbWFyaXplKHRvdGFsX3ZvdGUgPSBzdW0odmFsdWUpKSAlPiUgIyBEdW5ubyBob3cgcGx5ciBnb3QgaW4sIGJ1dCB3aGF0ZXZlci4NCiAgY29tcGxldGUodmFyaWFibGUpICU+JQ0KICB1bmdyb3VwKCkgJT4lIA0KICBncm91cF9ieShTdGF0ZU5hbWUpICU+JSANCiAgbXV0YXRlKHN1bV90b3RhbCA9IHN1bSh0b3RhbF92b3RlLCBuYS5ybT1UKSkgJT4lIA0KICBtdXRhdGUocHJvcG9ydGlvbiA9IGlmZWxzZShpcy5uYSh0b3RhbF92b3RlKSxOQSxwYXN0ZTAocm91bmQodG90YWxfdm90ZSAvIHN1bV90b3RhbCwgNCkqMTAwLCclJykpLA0KICAgICAgICAgcHJvcG9ydGlvbl9udW1lcmljID0gdG90YWxfdm90ZSAvIHN1bV90b3RhbCkgJT4lDQogIHNlbGVjdCgtc3VtX3RvdGFsKQ0KDQpjYW5kaWRhdGVfb3JkZXIgPC0gJ2NsaW50b24nICMgQ0hBTkdFIE1FDQoNCmxldmVsX29yZGVyPC0oZmlsdGVyKHZvdGVfYnlfc3RhdGUsdmFyaWFibGUgPT0gY2FuZGlkYXRlX29yZGVyKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICBzZWxlY3QoU3RhdGVOYW1lLCBwcm9wb3J0aW9uX251bWVyaWMpICU+JSANCiAgICAgICAgICAgICAgICAgICAgIGFycmFuZ2UoZGVzYyhwcm9wb3J0aW9uX251bWVyaWMpKSkkU3RhdGVOYW1lIA0KDQp2b3RlX2J5X3N0YXRlJFN0YXRlTmFtZTwtIGZhY3Rvcih2b3RlX2J5X3N0YXRlJFN0YXRlTmFtZSwgbGV2ZWxzID0gbGV2ZWxfb3JkZXIpDQp2b3RlX2J5X3N0YXRlJHZhcmlhYmxlPC1mYWN0b3Iodm90ZV9ieV9zdGF0ZSR2YXJpYWJsZSwgbGV2ZWxzID0gYygnb3RoZXInLCdzdGVpbicsJ2pvaG5zb24nLCd0cnVtcCcsJ2NsaW50b24nKSkNCg0KZ2dwbG90KHZvdGVfYnlfc3RhdGUsIGFlcyh4PVN0YXRlTmFtZSwgeT10b3RhbF92b3RlLCBmaWxsPXZhcmlhYmxlKSkgKyANCiAgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknLCBwb3NpdGlvbiA9ICdmaWxsJykgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCdjbGludG9uJyA9ICdibHVlJywgJ3RydW1wJyA9ICdyZWQnLCAnc3RlaW4nID0gJ2dyZWVuJywnam9obnNvbicgPSAneWVsbG93Jywnb3RoZXInID0gJ3B1cnBsZScpLCANCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICdDYW5kaWRhdGUnLA0KICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKCdvdGhlcicsJ3N0ZWluJywnam9obnNvbicsJ3RydW1wJywnY2xpbnRvbicpLA0KICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCdPdGhlcnMnLCdKaWxsIFN0ZWluJywnR2FyeSBKb2huc29uJywnRG9uYWxkIEogVHJ1bXAnLCdIaWxsYXJ5IENsaW50b24nKSkgKw0KICBsYWJzKHggPSBOVUxMLCB5ID0gJ1BlcmNlbnQgb2YgVm90ZScpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSArDQogIGdndGl0bGUoJ1BlcmNlbnQgb2YgVm90ZSBieSBTdGF0ZScsIHN1YnRpdGxlPScyMDE2IFVTQSBQcmVzaWRlbnRpYWwgRWxlY3Rpb24nKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpDQoNCmBgYA0KIyMjIENhbmRpZGF0ZSBWb3RlIFRvdGFscyBieSBDb3VudHkgV2l0aGluIFN0YXRlDQpGZWVsIGZyZWUgdG8gcGxheSB3aXRoIHRoZSB2YXJpYWJsZSBpbiB0aGlzIGNodW5rLg0KYGBge3J9DQpzdGF0ZTwtJ1Rlbm5lc3NlZScNCg0Kdm90ZV9ieV9jb3VudHk8LWZpbHRlcihkYXRhMjAxNiwgU3RhdGVOYW1lID09IHN0YXRlKSAlPiUgDQogIHNlbGVjdChDb3VudHlOYW1lLCBjbGludG9uLCB0cnVtcCwgam9obnNvbiwgc3RlaW4sIG90aGVyKSAlPiUgDQogIG1lbHQoaWQ9ICdDb3VudHlOYW1lJykgJT4lIA0KICBncm91cF9ieShDb3VudHlOYW1lLCB2YXJpYWJsZSkgJT4lIA0KICBkcGx5cjo6c3VtbWFyaXplKHRvdGFsX3ZvdGUgPSBzdW0odmFsdWUpKSAlPiUgIyBEdW5ubyBob3cgcGx5ciBnb3QgaW4sIGJ1dCB3aGF0ZXZlci4NCiAgY29tcGxldGUodmFyaWFibGUpICU+JQ0KICB1bmdyb3VwKCkgJT4lIA0KICBncm91cF9ieShDb3VudHlOYW1lKSAlPiUgDQogIG11dGF0ZShzdW1fdG90YWwgPSBzdW0odG90YWxfdm90ZSwgbmEucm09VCkpICU+JSANCiAgbXV0YXRlKHByb3BvcnRpb24gPSBpZmVsc2UoaXMubmEodG90YWxfdm90ZSksTkEscGFzdGUwKHJvdW5kKHRvdGFsX3ZvdGUgLyBzdW1fdG90YWwsIDQpKjEwMCwnJScpKSwNCiAgICAgICAgIHByb3BvcnRpb25fbnVtZXJpYyA9IHRvdGFsX3ZvdGUgLyBzdW1fdG90YWwpICU+JQ0KICBzZWxlY3QoLXN1bV90b3RhbCkNCg0KY2FuZGlkYXRlX29yZGVyIDwtICdjbGludG9uJyAjIENIQU5HRSBNRQ0KDQpsZXZlbF9vcmRlcjwtKGZpbHRlcih2b3RlX2J5X2NvdW50eSx2YXJpYWJsZSA9PSBjYW5kaWRhdGVfb3JkZXIpICU+JSANCiAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChDb3VudHlOYW1lLCBwcm9wb3J0aW9uX251bWVyaWMpICU+JSANCiAgICAgICAgICAgICAgICAgICAgIGFycmFuZ2UoZGVzYyhwcm9wb3J0aW9uX251bWVyaWMpKSkkQ291bnR5TmFtZSANCg0Kdm90ZV9ieV9jb3VudHkkQ291bnR5TmFtZTwtIGZhY3Rvcih2b3RlX2J5X2NvdW50eSRDb3VudHlOYW1lLCBsZXZlbHMgPSBsZXZlbF9vcmRlcikNCnZvdGVfYnlfY291bnR5JHZhcmlhYmxlPC1mYWN0b3Iodm90ZV9ieV9jb3VudHkkdmFyaWFibGUsIGxldmVscyA9IGMoJ290aGVyJywnc3RlaW4nLCdqb2huc29uJywndHJ1bXAnLCdjbGludG9uJykpDQoNCmdncGxvdCh2b3RlX2J5X2NvdW50eSwgYWVzKHg9Q291bnR5TmFtZSwgeT10b3RhbF92b3RlLCBmaWxsPXZhcmlhYmxlKSkgKyANCiAgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknLCBwb3NpdGlvbiA9ICdmaWxsJykgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCdjbGludG9uJyA9ICdibHVlJywgJ3RydW1wJyA9ICdyZWQnLCAnc3RlaW4nID0gJ2dyZWVuJywnam9obnNvbicgPSAneWVsbG93Jywnb3RoZXInID0gJ3B1cnBsZScpLCANCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICdDYW5kaWRhdGUnLA0KICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKCdvdGhlcicsJ3N0ZWluJywnam9obnNvbicsJ3RydW1wJywnY2xpbnRvbicpLA0KICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCdPdGhlcnMnLCdKaWxsIFN0ZWluJywnR2FyeSBKb2huc29uJywnRG9uYWxkIEogVHJ1bXAnLCdIaWxsYXJ5IENsaW50b24nKSkgKw0KICBsYWJzKHggPSBOVUxMLCB5ID0gJ1BlcmNlbnQgb2YgVm90ZScpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSArDQogIGdndGl0bGUocGFzdGUwKCdQZXJjZW50IG9mIFZvdGUgYnkgQ291bnR5IC0gJyxzdGF0ZSksIHN1YnRpdGxlPScyMDE2IFVTQSBQcmVzaWRlbnRpYWwgRWxlY3Rpb24nKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpDQoNCmBgYA0KIyMjVGVybmFyeSBQbG90DQoqIExldCdzIHRyeSBzb21ldGhpbmcgY3Jhenk/IQ0KKiBIZXJlJ3MgYW4gaW50ZXJlc3RpbmcgaWRlYSBmb3IgbG9va2luZyBhdCB0aGUgY291bnR5IGJ5IGNvdW50eSByZXN1bHRzLg0KICAgICsgVXRhaCBoYWQgYSBoaWdoIHZvdGUgdG90YWwgZm9yIEV2YW4gTWNNaWxsaW4sIGFuZCB0aGlzIGlzIGEgd2F5IHRvIHZpc3VhbGl6ZSBVdGFoJ3MgdW5pcXVlbmVzcy4NCmBgYHtyfQ0KbGlicmFyeShnZ3Rlcm4pDQoNCnRlcm5hcnlfdm90ZTwtbXV0YXRlKGRhdGEyMDE2LCB0aGlyZF9wYXJ0eSA9IGpvaG5zb24gKyBzdGVpbiArIG90aGVyKSAlPiUgDQogIHNlbGVjdChDb3VudHksIFN0YXRlTmFtZSwgY2xpbnRvbiwgdHJ1bXAsIHRoaXJkX3BhcnR5KSAlPiUgDQogIG1lbHQoaWQ9IGMoJ0NvdW50eScsJ1N0YXRlTmFtZScpKSAlPiUgDQogIGdyb3VwX2J5KENvdW50eSwgU3RhdGVOYW1lLCB2YXJpYWJsZSkgJT4lIA0KICBkcGx5cjo6c3VtbWFyaXplKHRvdGFsX3ZvdGUgPSBzdW0odmFsdWUpKSAlPiUgIyBEdW5ubyBob3cgcGx5ciBnb3QgaW4sIGJ1dCB3aGF0ZXZlci4NCiAgY29tcGxldGUodmFyaWFibGUpICU+JQ0KICB1bmdyb3VwKCkgJT4lIA0KICBncm91cF9ieShDb3VudHkpICU+JSANCiAgbXV0YXRlKHN1bV90b3RhbCA9IHN1bSh0b3RhbF92b3RlLCBuYS5ybT1UKSkgJT4lIA0KICBtdXRhdGUocHJvcG9ydGlvbl9udW1lcmljID0gdG90YWxfdm90ZSAvIHN1bV90b3RhbCkgJT4lDQogIHNlbGVjdCgtc3VtX3RvdGFsLCAtdG90YWxfdm90ZSkgJT4lIA0KICBzcHJlYWQoa2V5ID0gdmFyaWFibGUsIHZhbHVlID0gcHJvcG9ydGlvbl9udW1lcmljKQ0KDQp0ZXJuYXJ5X3ZvdGUkU3RhdGVOYW1lPC1zYXBwbHkodGVybmFyeV92b3RlJFN0YXRlTmFtZSwgZnVuY3Rpb24oaSkgaWZlbHNlKGk9PSdVdGFoJywnVXRhaCcsJ05vdCBVdGFoJykpDQoNCmdndGVybih0ZXJuYXJ5X3ZvdGUsIGFlcyh4PWNsaW50b24sIHk9dHJ1bXAsIHo9dGhpcmRfcGFydHksIGNvbG9yPVN0YXRlTmFtZSkpKw0KICBnZW9tX3BvaW50KGFlcyhhbHBoYSA9IDAuMikpDQoNCmBgYA0KDQojIyNQYXJ0eSBSZWdpc3RyYXRpb24gYnkgU3RhdGUNCk5vdCBhbGwgc3RhdGVzIGhhdmUgcGFydGlzYW4gcmVnaXN0cmF0aW9uLg0KYGBge3J9DQpwYXJ0eV9yZWdpc3RyYXRpb24gPC0gc2VsZWN0KHZvdGVyUmVnMjAxNiwgU3RhdGUsIERSZWcsIFJSZWcsIE9SZWcsIEdSZWcsIExSZWcsIE5SZWcpICU+JSANCiAgbWVsdChpZD0gJ1N0YXRlJykgJT4lIA0KICBncm91cF9ieShTdGF0ZSwgdmFyaWFibGUpICU+JSANCiAgZHBseXI6OnN1bW1hcml6ZSh0b3RhbF9yZWcgPSBzdW0odmFsdWUpKSAlPiUgDQogIGNvbXBsZXRlKHZhcmlhYmxlKSAlPiUNCiAgdW5ncm91cCgpICU+JSANCiAgZ3JvdXBfYnkoU3RhdGUpICU+JSANCiAgbXV0YXRlKHN1bV90b3RhbCA9IHN1bSh0b3RhbF9yZWcsIG5hLnJtPVQpKSAlPiUgDQogIG11dGF0ZShwcm9wb3J0aW9uID0gaWZlbHNlKGlzLm5hKHRvdGFsX3JlZyksTkEscGFzdGUwKHJvdW5kKHRvdGFsX3JlZyAvIHN1bV90b3RhbCwgNCkqMTAwLCclJykpLA0KICAgICAgICAgcHJvcG9ydGlvbl9udW1lcmljID0gdG90YWxfcmVnIC8gc3VtX3RvdGFsKSAlPiUNCiAgc2VsZWN0KC1zdW1fdG90YWwpDQoNCnBhcnR5X3JlZ2lzdHJhdGlvbiRTdGF0ZTwtc2FwcGx5KHBhcnR5X3JlZ2lzdHJhdGlvbiRTdGF0ZSwgZnVuY3Rpb24oaSkgbmFtZXMoc3RhdGVfbmFtZXMpW3doaWNoKHN0YXRlX25hbWVzID09IGkpXSkNCg0Kbm9uX3BhcnRpc2FuX3N0YXRlczwtKGZpbHRlcihwYXJ0eV9yZWdpc3RyYXRpb24sIHZhcmlhYmxlID09ICdOUmVnJykgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHByb3BvcnRpb25fbnVtZXJpYyA9PSAxKSkkU3RhdGUNCnBhcnR5X3JlZ2lzdHJhdGlvbiA8LSBmaWx0ZXIocGFydHlfcmVnaXN0cmF0aW9uLCAhKFN0YXRlICVpbiUgbm9uX3BhcnRpc2FuX3N0YXRlcykpDQoNCnBhcnR5X29yZGVyIDwtICdEUmVnJyAjIENIQU5HRSBNRQ0KDQpsZXZlbF9vcmRlcjwtKGZpbHRlcihwYXJ0eV9yZWdpc3RyYXRpb24sdmFyaWFibGUgPT0gcGFydHlfb3JkZXIpICU+JSANCiAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChTdGF0ZSwgcHJvcG9ydGlvbl9udW1lcmljKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICBhcnJhbmdlKGRlc2MocHJvcG9ydGlvbl9udW1lcmljKSkpJFN0YXRlDQoNCnBhcnR5X3JlZ2lzdHJhdGlvbiRTdGF0ZTwtIGZhY3RvcihwYXJ0eV9yZWdpc3RyYXRpb24kU3RhdGUsIGxldmVscyA9IGxldmVsX29yZGVyKQ0KcGFydHlfcmVnaXN0cmF0aW9uJHZhcmlhYmxlPC1mYWN0b3IocGFydHlfcmVnaXN0cmF0aW9uJHZhcmlhYmxlLCBsZXZlbHMgPSBjKCdOUmVnJywnT1JlZycsJ0dSZWcnLCdMUmVnJywnUlJlZycsJ0RSZWcnKSkNCg0KZ2dwbG90KHBhcnR5X3JlZ2lzdHJhdGlvbiwgYWVzKHg9U3RhdGUsIHk9dG90YWxfcmVnLCBmaWxsPXZhcmlhYmxlKSkgKyANCiAgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknLCBwb3NpdGlvbiA9ICdmaWxsJykgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCdEUmVnJyA9ICdibHVlJywgJ1JSZWcnID0gJ3JlZCcsICdHUmVnJyA9ICdncmVlbicsJ0xSZWcnID0gJ3llbGxvdycsJ09SZWcnID0gJ3B1cnBsZScsJ05SZWcnID0gJ2dyZXknKSwNCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICdDYW5kaWRhdGUnLA0KICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKCdOUmVnJywnT1JlZycsJ0dSZWcnLCdMUmVnJywnUlJlZycsJ0RSZWcnKSwNCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygnTm8gUGFydHknLCdPdGhlciBQYXJ0eScsJ0dyZWVuJywnTGliZXJ0YXJpYW4nLCdSZXB1YmxpY2FuJywnRGVtb2NyYXRpYycpKSArDQogIGxhYnMoeCA9IE5VTEwsIHkgPSAnUGVyY2VudCBvZiBSZWdpc3RlcmVkIFZvdGVycycpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSArDQogIGdndGl0bGUoJ1BlcmNlbnQgb2YgVm90ZXIgUmVnaXN0cmF0aW9uIGJ5IFN0YXRlJywgc3VidGl0bGU9JzIwMTYnKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpDQpgYGANCkxvb2tzIGxpa2Ugd2UgaGF2ZSBhIGJpdCBvZiBhbiBpc3N1ZSBoZXJlIHdpdGggT3RoZXIgYW5kIE5vbi1wYXJ0aXNhbiByZWdpc3RyYXRpb24uICBORSBhbmQgV1YgYXJlIGFsbCAiT3RoZXIiLg0KDQojIyNQYXJ0aXNhbiBSZWdpc3RyYXRpb24gYnkgQ291bnR5IHdpdGhpbiBTdGF0ZQ0KRmVlbCBmcmVlIHRvIHBsYXkgd2l0aCB0aGUgdmFyaWFibGUgaW4gdGhpcy4NCmBgYHtyfQ0Kc3RhdGUgPC0gJ1dlc3QgVmlyZ2luaWEnDQoNCnBhcnR5X3JlZ2lzdHJhdGlvbl9jIDwtIGZpbHRlcihkYXRhMjAxNiwgU3RhdGVOYW1lID09IHN0YXRlKSAlPiUgIA0KICBzZWxlY3QoQ291bnR5TmFtZSwgRFJlZywgUlJlZywgT1JlZywgR1JlZywgTFJlZywgTlJlZykgJT4lIA0KICBtZWx0KGlkPSAnQ291bnR5TmFtZScpICU+JSANCiAgZ3JvdXBfYnkoQ291bnR5TmFtZSwgdmFyaWFibGUpICU+JSANCiAgZHBseXI6OnN1bW1hcml6ZSh0b3RhbF9yZWcgPSBzdW0odmFsdWUpKSAlPiUgDQogIGNvbXBsZXRlKHZhcmlhYmxlKSAlPiUNCiAgdW5ncm91cCgpICU+JSANCiAgZ3JvdXBfYnkoQ291bnR5TmFtZSkgJT4lIA0KICBtdXRhdGUoc3VtX3RvdGFsID0gc3VtKHRvdGFsX3JlZywgbmEucm09VCkpICU+JSANCiAgbXV0YXRlKHByb3BvcnRpb24gPSBpZmVsc2UoaXMubmEodG90YWxfcmVnKSxOQSxwYXN0ZTAocm91bmQodG90YWxfcmVnIC8gc3VtX3RvdGFsLCA0KSoxMDAsJyUnKSksDQogICAgICAgICBwcm9wb3J0aW9uX251bWVyaWMgPSB0b3RhbF9yZWcgLyBzdW1fdG90YWwpICU+JQ0KICBzZWxlY3QoLXN1bV90b3RhbCkNCg0KcGFydHlfb3JkZXIgPC0gJ0RSZWcnICMgQ0hBTkdFIE1FDQoNCmxldmVsX29yZGVyPC0oZmlsdGVyKHBhcnR5X3JlZ2lzdHJhdGlvbl9jLHZhcmlhYmxlID09IHBhcnR5X29yZGVyKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICBzZWxlY3QoQ291bnR5TmFtZSwgcHJvcG9ydGlvbl9udW1lcmljKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICBhcnJhbmdlKGRlc2MocHJvcG9ydGlvbl9udW1lcmljKSkpJENvdW50eU5hbWUNCg0KcGFydHlfcmVnaXN0cmF0aW9uX2MkQ291bnR5TmFtZTwtIGZhY3RvcihwYXJ0eV9yZWdpc3RyYXRpb25fYyRDb3VudHlOYW1lLCBsZXZlbHMgPSBsZXZlbF9vcmRlcikNCnBhcnR5X3JlZ2lzdHJhdGlvbl9jJHZhcmlhYmxlPC1mYWN0b3IocGFydHlfcmVnaXN0cmF0aW9uX2MkdmFyaWFibGUsIGxldmVscyA9IGMoJ05SZWcnLCdPUmVnJywnR1JlZycsJ0xSZWcnLCdSUmVnJywnRFJlZycpKQ0KDQpnZ3Bsb3QocGFydHlfcmVnaXN0cmF0aW9uX2MsIGFlcyh4PUNvdW50eU5hbWUsIHk9dG90YWxfcmVnLCBmaWxsPXZhcmlhYmxlKSkgKyANCiAgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknLCBwb3NpdGlvbiA9ICdmaWxsJykgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCdEUmVnJyA9ICdibHVlJywgJ1JSZWcnID0gJ3JlZCcsICdHUmVnJyA9ICdncmVlbicsJ0xSZWcnID0gJ3llbGxvdycsJ09SZWcnID0gJ3B1cnBsZScsJ05SZWcnID0gJ2dyZXknKSwNCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICdDYW5kaWRhdGUnLA0KICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKCdOUmVnJywnT1JlZycsJ0dSZWcnLCdMUmVnJywnUlJlZycsJ0RSZWcnKSwNCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygnTm8gUGFydHknLCdPdGhlciBQYXJ0eScsJ0dyZWVuJywnTGliZXJ0YXJpYW4nLCdSZXB1YmxpY2FuJywnRGVtb2NyYXRpYycpKSArDQogIGxhYnMoeCA9IE5VTEwsIHkgPSAnUGVyY2VudCBvZiBSZWdpc3RlcmVkIFZvdGVycycpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSArDQogIGdndGl0bGUoJ1BlcmNlbnQgb2YgVm90ZXIgUmVnaXN0cmF0aW9uIGJ5IENvdW50eScsIHN1YnRpdGxlPXBhc3RlMChzdGF0ZSwnIC0gMjAxNicpKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpDQpgYGANCg0KIyMjVm90ZXIgVHVybm91dCBieSBTdGF0ZQ0KKiBXZSBkb24ndCBoYXZlIGdyZWF0IGRhdGEgdG8gZG8gdGhpcywgYmVjdWFzZSB0aGUgY2Vuc3VzIGJyYWNrZXQgaXMgZnJvbSBhZ2UgMTUtMTksIHdoaWNoIGN1dHMgb3V0IHR3byB5ZWFycyBvZiB2b3RpbmcgYWdlLg0KKiBNYXliZSBiZWNhdXNlIG9mIHRoaXMgKGJ1dCBtYXliZSBub3QhKSB0aGVyZSBhcmUgc29tZSBzdGF0ZXMgd2hlcmUgKHZvdGVkK3JlZ2lzdGVyZWQgYnV0IGRpZG4ndCB2b3RlKSA+IHRvdGFsIHZvdGluZyBwb3B1bGF0aW9uLg0KICAgICsgRXZlbiBpZiB0aGUgaXNzdWUgaXMgbm90IHRoZSBjZW5zdXMgcG9wdWxhdGlvbnMsIGl0IGNvdWxkIGJlIG1lcmVseSBvdXQgb2YgZGF0ZSB2b3RlciByZWdpc3RyYXRpb24gZGF0YS4NCmBgYHtyfQ0KdHVybm91dF9kYXRhIDwtIGdyb3VwX2J5KGRhdGEyMDE2LCBTdGF0ZU5hbWUpICU+JSANCiAgZHBseXI6OnN1bW1hcml6ZSh0b3RhbF92b3RlcyA9IHN1bShjbGludG9uLHRydW1wLGpvaG5zb24sc3RlaW4sb3RoZXIsIG5hLnJtPVQpLA0KICAgICAgICAgICAgICAgICAgIHRvdGFsX3JlZ19ub192b3RlID0gc3VtKERSZWcsUlJlZyxPUmVnLEdSZWcsTFJlZyxOUmVnLCBuYS5ybT1UKS10b3RhbF92b3RlcywNCiAgICAgICAgICAgICAgICAgICB0b3RhbF9ub3RfcmVnaXN0ZXJlZCA9IGlmZWxzZShzdW0oVG90YWxQb3B1bGF0aW9uKS0gc3VtKEFnZTBfNCktIHN1bShBZ2U1XzkpLSBzdW0oQWdlMTBfMTQpIC0gc3VtKEFnZTE1XzE5KSAtDQogICAgICAgICAgICAgICAgICAgICB0b3RhbF9yZWdfbm9fdm90ZSAtIHRvdGFsX3ZvdGVzPDAsTkEsc3VtKFRvdGFsUG9wdWxhdGlvbiktIHN1bShBZ2UwXzQpLSBzdW0oQWdlNV85KS0gc3VtKEFnZTEwXzE0KSAtIA0KICAgICAgICAgICAgICAgICAgICAgc3VtKEFnZTE1XzE5KSAtIHRvdGFsX3JlZ19ub192b3RlIC0gdG90YWxfdm90ZXMpKSAlPiUgIA0KICBtZWx0KGlkID0gJ1N0YXRlTmFtZScpICU+JSANCiAgZ3JvdXBfYnkoU3RhdGVOYW1lLCB2YXJpYWJsZSkgJT4lIA0KICBkcGx5cjo6c3VtbWFyaXplKHRvdGFsX3BvcCA9IHN1bSh2YWx1ZSkpICU+JSANCiAgY29tcGxldGUodmFyaWFibGUpICU+JQ0KICB1bmdyb3VwKCkgJT4lIA0KICBncm91cF9ieShTdGF0ZU5hbWUpICU+JSANCiAgbXV0YXRlKHN1bV90b3RhbCA9IHN1bSh0b3RhbF9wb3AsIG5hLnJtPVQpKSAlPiUgDQogIG11dGF0ZShwcm9wb3J0aW9uID0gaWZlbHNlKGlzLm5hKHRvdGFsX3BvcCksTkEscGFzdGUwKHJvdW5kKHRvdGFsX3BvcCAvIHN1bV90b3RhbCwgNCkqMTAwLCclJykpLA0KICAgICAgICAgcHJvcG9ydGlvbl9udW1lcmljID0gdG90YWxfcG9wIC8gc3VtX3RvdGFsKSAlPiUNCiAgc2VsZWN0KC1zdW1fdG90YWwpDQoNCnR1cm5vdXRfZGF0YSR2YXJpYWJsZTwtZmFjdG9yKHR1cm5vdXRfZGF0YSR2YXJpYWJsZSwgbGV2ZWxzID0gYygndG90YWxfbm90X3JlZ2lzdGVyZWQnLCd0b3RhbF9yZWdfbm9fdm90ZScsJ3RvdGFsX3ZvdGVzJykpDQoNCmdncGxvdCh0dXJub3V0X2RhdGEsIGFlcyh4PVN0YXRlTmFtZSwgeT10b3RhbF9wb3AsIGZpbGw9dmFyaWFibGUpKSArIA0KICBnZW9tX2JhcihzdGF0PSdpZGVudGl0eScsIHBvc2l0aW9uID0gJ2ZpbGwnKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoJ3RvdGFsX3ZvdGVzJyA9ICdncmVlbicsICd0b3RhbF9yZWdfbm9fdm90ZScgPSAncHVycGxlJywgJ3RvdGFsX25vdF9yZWdpc3RlcmVkJyA9ICdncmV5JyksDQogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAnUG9wdWxhdGlvbicsDQogICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoJ3RvdGFsX3ZvdGVzJywndG90YWxfcmVnX25vX3ZvdGUnLCd0b3RhbF9ub3RfcmVnaXN0ZXJlZCcpLA0KICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCdWb3RlZCcsJ1JlZ2lzdGVyZWQsIGJ1dCBkaWQgbm90IHZvdGUnLCdOb3QgUmVnaXN0ZXJlZCcpKSArDQogIGxhYnMoeCA9IE5VTEwsIHkgPSAnUGVyY2VudCBvZiBQb3B1bGF0aW9uJykrDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgZ2d0aXRsZSgnVm90ZXIgVHVybm91dCBieSBTdGF0ZScsIHN1YnRpdGxlPScyMDE2JykgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQ0KDQpgYGANCiMjI1ZvdGVyIFR1cm5vdXQgYnkgQ291bnR5IFdpdGhpbiBTdGF0ZQ0KYGBge3J9DQpzdGF0ZSA8LSAnS2VudHVja3knDQoNCnR1cm5vdXRfZGF0YV9jIDwtIGZpbHRlcihkYXRhMjAxNiwgU3RhdGVOYW1lID09IHN0YXRlKSAlPiUgDQogIGdyb3VwX2J5KENvdW50eU5hbWUpICU+JSANCiAgZHBseXI6OnN1bW1hcml6ZSh0b3RhbF92b3RlcyA9IHN1bShjbGludG9uLHRydW1wLGpvaG5zb24sc3RlaW4sb3RoZXIsIG5hLnJtPVQpLA0KICAgICAgICAgICAgICAgICAgIHRvdGFsX3JlZ19ub192b3RlID0gc3VtKERSZWcsUlJlZyxPUmVnLEdSZWcsTFJlZyxOUmVnLCBuYS5ybT1UKS10b3RhbF92b3RlcywNCiAgICAgICAgICAgICAgICAgICB0b3RhbF9ub3RfcmVnaXN0ZXJlZCA9IGlmZWxzZShzdW0oVG90YWxQb3B1bGF0aW9uKS0gc3VtKEFnZTBfNCktIHN1bShBZ2U1XzkpLSBzdW0oQWdlMTBfMTQpIC0gc3VtKEFnZTE1XzE5KSAtDQogICAgICAgICAgICAgICAgICAgICB0b3RhbF9yZWdfbm9fdm90ZSAtIHRvdGFsX3ZvdGVzPDAsTkEsc3VtKFRvdGFsUG9wdWxhdGlvbiktIHN1bShBZ2UwXzQpLSBzdW0oQWdlNV85KS0gc3VtKEFnZTEwXzE0KSAtIA0KICAgICAgICAgICAgICAgICAgICAgc3VtKEFnZTE1XzE5KSAtIHRvdGFsX3JlZ19ub192b3RlIC0gdG90YWxfdm90ZXMpKSAlPiUgIA0KICBtZWx0KGlkID0gJ0NvdW50eU5hbWUnKSAlPiUgDQogIGdyb3VwX2J5KENvdW50eU5hbWUsIHZhcmlhYmxlKSAlPiUgDQogIGRwbHlyOjpzdW1tYXJpemUodG90YWxfcG9wID0gc3VtKHZhbHVlKSkgJT4lIA0KICBjb21wbGV0ZSh2YXJpYWJsZSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUgDQogIGdyb3VwX2J5KENvdW50eU5hbWUpICU+JSANCiAgbXV0YXRlKHN1bV90b3RhbCA9IHN1bSh0b3RhbF9wb3AsIG5hLnJtPVQpKSAlPiUgDQogIG11dGF0ZShwcm9wb3J0aW9uID0gaWZlbHNlKGlzLm5hKHRvdGFsX3BvcCksTkEscGFzdGUwKHJvdW5kKHRvdGFsX3BvcCAvIHN1bV90b3RhbCwgNCkqMTAwLCclJykpLA0KICAgICAgICAgcHJvcG9ydGlvbl9udW1lcmljID0gdG90YWxfcG9wIC8gc3VtX3RvdGFsKSAlPiUNCiAgc2VsZWN0KC1zdW1fdG90YWwpDQoNCnR1cm5vdXRfZGF0YV9jJHZhcmlhYmxlPC1mYWN0b3IodHVybm91dF9kYXRhX2MkdmFyaWFibGUsIGxldmVscyA9IGMoJ3RvdGFsX25vdF9yZWdpc3RlcmVkJywndG90YWxfcmVnX25vX3ZvdGUnLCd0b3RhbF92b3RlcycpKQ0KDQpnZ3Bsb3QodHVybm91dF9kYXRhX2MsIGFlcyh4PUNvdW50eU5hbWUsIHk9dG90YWxfcG9wLCBmaWxsPXZhcmlhYmxlKSkgKyANCiAgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknLCBwb3NpdGlvbiA9ICdmaWxsJykgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCd0b3RhbF92b3RlcycgPSAnZ3JlZW4nLCAndG90YWxfcmVnX25vX3ZvdGUnID0gJ3B1cnBsZScsICd0b3RhbF9ub3RfcmVnaXN0ZXJlZCcgPSAnZ3JleScpLA0KICAgICAgICAgICAgICAgICAgICBuYW1lID0gJ1BvcHVsYXRpb24nLA0KICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKCd0b3RhbF92b3RlcycsJ3RvdGFsX3JlZ19ub192b3RlJywndG90YWxfbm90X3JlZ2lzdGVyZWQnKSwNCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygnVm90ZWQnLCdSZWdpc3RlcmVkLCBidXQgZGlkIG5vdCB2b3RlJywnTm90IFJlZ2lzdGVyZWQnKSkgKw0KICBsYWJzKHggPSBOVUxMLCB5ID0gJ1BlcmNlbnQgb2YgUG9wdWxhdGlvbicpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSArDQogIGdndGl0bGUoJ1ZvdGVyIFR1cm5vdXQgYnkgQ291bnR5Jywgc3VidGl0bGU9cGFzdGUwKHN0YXRlLCcsIDIwMTYnKSkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQ0KYGBgDQoNCg0KIyMjVmljdG9yeSBNYXJnaW5zDQoqIE5vdCBxdWl0ZSBzdXJlIHdoYXQgd2UgYXJlIGdvaW5nIGZvciwgaGVyZS4NCg0KIyMjRGVtb2dyYXBoaWMgLyBFY29ub21pYyBWYXJpYWJsZXMNCiogTGV0J3MgbG9vayBhdCAlIG9mIHZvdGUgZmFjZXRlZCBvdmVyIHNvbWUgZGlmZmVyZW50IHZhcmlhYmxlcw0KKiBUaGlzIGdyYXBoaWMgcHJvZHVjZXMgY291bnR5IGJ5IGNvdW50eSByZXN1bHRzIGZhY2V0dGluZyBieSBxdWludGlsZSBvZiBEZW1vZ3JhcGhpYy9FY29ub21pYyB2YXJpYWJsZQ0KICAgICsgWW91IGNhbiBjaGFuZ2UgdGhlIHZhcmlhYmxlIGluIHRoZSBjb2RlIHRvIHNlZSBvdGhlciB2YXJpYWJsZXMuDQoqIFRoZXJlIGlzIG9uZSBjYXRlZ29yaWNhbCB2YXJpYWJsZSwgdGhlIGNvZGUgZm9yIHByb2R1Y2luZyBpdCdzIGZhY2V0dGVkIHBsb3QgaXMgaW4gY29tbWVudGVkIGluIHRoaXMgY2h1bmsuDQpgYGB7cn0NCkRlbW9fRmFjdG9ycyA8LSBzZWxlY3QoZGF0YTIwMTYsIENvdW50eSwgckRSUGN0LCBOQ0hTX1VyYmFuUnVyYWwyMDEzLCBUb3RhbFBvcHVsYXRpb24sIE1lZGlhbkFnZSwgTWVkaWFuSG91c2Vob2xkSW5jb21lLCBTaW1wc29uRGl2ZXJzaXR5SW5kZXgsIHByb3BXaGl0ZSwgcHJvcEJsYWNrLCBwcm9wTWZnMjAxNSwgcHJvcEhTLCBwcm9wTW9yZUhTLCBwcm9wVW5lbXAsIHByb3BFbGRlcnMsIHByb3BOTWFycmllZCkNCg0KbG0ockRSUGN0fi4sc2VsZWN0KERlbW9fRmFjdG9ycywtQ291bnR5KSkgJT4lIHN1bW1hcnkoKQ0KDQpEZW1vX0ZhY3RvcnMgPC0gc2VsZWN0KGRhdGEyMDE2LCBDb3VudHksIHRydW1wLCBjbGludG9uLCBqb2huc29uLCBzdGVpbiwgb3RoZXIsIE5DSFNfVXJiYW5SdXJhbDIwMTMsIFRvdGFsUG9wdWxhdGlvbiwgTWVkaWFuQWdlLCBNZWRpYW5Ib3VzZWhvbGRJbmNvbWUsIFNpbXBzb25EaXZlcnNpdHlJbmRleCwgcHJvcFdoaXRlLCBwcm9wQmxhY2ssIHByb3BNZmcyMDE1LCBwcm9wSFMsIHByb3BNb3JlSFMsIHByb3BVbmVtcCwgcHJvcEVsZGVycywgcHJvcE5NYXJyaWVkKQ0KDQp2b3RlX2J5X2NvdW50eV9mPC1zZWxlY3QoRGVtb19GYWN0b3JzLCBDb3VudHksIGNsaW50b24sIHRydW1wLCBqb2huc29uLCBzdGVpbiwgb3RoZXIpICU+JSANCiAgbWVsdChpZD0gYygnQ291bnR5JykpICU+JSANCiAgZ3JvdXBfYnkoQ291bnR5LCB2YXJpYWJsZSkgJT4lIA0KICBkcGx5cjo6c3VtbWFyaXplKHRvdGFsX3ZvdGUgPSBzdW0odmFsdWUpKSAlPiUgIyBEdW5ubyBob3cgcGx5ciBnb3QgaW4sIGJ1dCB3aGF0ZXZlci4NCiAgY29tcGxldGUodmFyaWFibGUpICU+JQ0KICB1bmdyb3VwKCkgJT4lIA0KICBncm91cF9ieShDb3VudHkpICU+JSANCiAgbXV0YXRlKHN1bV90b3RhbCA9IHN1bSh0b3RhbF92b3RlLCBuYS5ybT1UKSkgJT4lIA0KICBtdXRhdGUocHJvcG9ydGlvbiA9IGlmZWxzZShpcy5uYSh0b3RhbF92b3RlKSxOQSxwYXN0ZTAocm91bmQodG90YWxfdm90ZSAvIHN1bV90b3RhbCwgNCkqMTAwLCclJykpLA0KICAgICAgICAgcHJvcG9ydGlvbl9udW1lcmljID0gdG90YWxfdm90ZSAvIHN1bV90b3RhbCkgJT4lDQogIHNlbGVjdCgtc3VtX3RvdGFsKQ0KDQp2b3RlX2J5X2NvdW50eV9mIDwtIGxlZnRfam9pbih2b3RlX2J5X2NvdW50eV9mLCBEZW1vX0ZhY3RvcnMsIGJ5PSdDb3VudHknKQ0KDQpjYW5kaWRhdGVfb3JkZXIgPC0gJ2NsaW50b24nICMgQ0hBTkdFIE1FDQoNCmxldmVsX29yZGVyPC0oZmlsdGVyKHZvdGVfYnlfY291bnR5X2YsdmFyaWFibGUgPT0gY2FuZGlkYXRlX29yZGVyKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICBzZWxlY3QoQ291bnR5LCBwcm9wb3J0aW9uX251bWVyaWMpICU+JSANCiAgICAgICAgICAgICAgICAgICAgIGFycmFuZ2UoZGVzYyhwcm9wb3J0aW9uX251bWVyaWMpKSkkQ291bnR5IA0KDQp2b3RlX2J5X2NvdW50eV9mJENvdW50eTwtIGZhY3Rvcih2b3RlX2J5X2NvdW50eV9mJENvdW50eSwgbGV2ZWxzID0gbGV2ZWxfb3JkZXIpDQp2b3RlX2J5X2NvdW50eV9mJHZhcmlhYmxlPC1mYWN0b3Iodm90ZV9ieV9jb3VudHlfZiR2YXJpYWJsZSwgbGV2ZWxzID0gYygnb3RoZXInLCdzdGVpbicsJ2pvaG5zb24nLCd0cnVtcCcsJ2NsaW50b24nKSkNCg0KIyBnZ3Bsb3QoZmlsdGVyKHZvdGVfYnlfY291bnR5X2YsICFpcy5uYShOQ0hTX1VyYmFuUnVyYWwyMDEzKSksIGFlcyh4PUNvdW50eSwgeT10b3RhbF92b3RlLCBmaWxsPXZhcmlhYmxlKSkgKyANCiMgICBnZW9tX2JhcihzdGF0PSdpZGVudGl0eScsIHBvc2l0aW9uID0gJ2ZpbGwnKSArDQojICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygnY2xpbnRvbicgPSAnYmx1ZScsICd0cnVtcCcgPSAncmVkJywgJ3N0ZWluJyA9ICdncmVlbicsJ2pvaG5zb24nID0gJ3llbGxvdycsJ290aGVyJyA9ICdwdXJwbGUnKSwgDQojICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICdDYW5kaWRhdGUnLA0KIyAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoJ290aGVyJywnc3RlaW4nLCdqb2huc29uJywndHJ1bXAnLCdjbGludG9uJyksDQojICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygnT3RoZXJzJywnSmlsbCBTdGVpbicsJ0dhcnkgSm9obnNvbicsJ0RvbmFsZCBKIFRydW1wJywnSGlsbGFyeSBDbGludG9uJykpICsNCiMgICBsYWJzKHggPSBOVUxMLCB5ID0gJ1BlcmNlbnQgb2YgVm90ZScpKw0KIyAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiMgICBnZ3RpdGxlKCdQZXJjZW50IG9mIFZvdGUgYnkgQ291bnR5Jywgc3VidGl0bGU9JzIwMTYgVVNBIFByZXNpZGVudGlhbCBFbGVjdGlvbicpICsNCiMgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpKSArDQojICAgZmFjZXRfd3JhcCh+TkNIU19VcmJhblJ1cmFsMjAxMywgc2NhbGVzID0gJ2ZyZWVfeCcpDQoNCmZhY2V0dGluZ192YXJpYWJsZSA8LSAnTWVkaWFuQWdlJyAjQ2hhbmdlIE1lDQoNCnZvdGVfYnlfY291bnR5X2YkZmN0IDwtIGN1dCh2b3RlX2J5X2NvdW50eV9mW1tmYWNldHRpbmdfdmFyaWFibGVdXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygwLHF1YW50aWxlKHZvdGVfYnlfY291bnR5X2ZbW2ZhY2V0dGluZ192YXJpYWJsZV1dLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9icyA9IGMoMC4xLCAwLjI1LCAwLjUsIDAuNzUsIDAuOSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm0gPSBUKSxJbmYpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWRfcmVzdWx0ID0gVCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCdMb3dlc3QgMTAlJywnMTB0aCAtIDI1dGggJWlsZScsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnMjV0aCAlaWxlIC0gTWVkaWFuJywnTWVkaWFuIC0gNzV0aCAlaWxlJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc3NXRoIC0gOTB0aCAlaWxlJywgJ1RvcCAxMCUnKSkNCg0KZ2dwbG90KGZpbHRlcih2b3RlX2J5X2NvdW50eV9mLCAhaXMubmEoZmN0KSksIGFlcyh4PUNvdW50eSwgeT10b3RhbF92b3RlLCBmaWxsPXZhcmlhYmxlKSkgKyANCiAgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknLCBwb3NpdGlvbiA9ICdmaWxsJykgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCdjbGludG9uJyA9ICdibHVlJywgJ3RydW1wJyA9ICdyZWQnLCAnc3RlaW4nID0gJ2dyZWVuJywnam9obnNvbicgPSAneWVsbG93Jywnb3RoZXInID0gJ3B1cnBsZScpLCANCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICdDYW5kaWRhdGUnLA0KICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKCdvdGhlcicsJ3N0ZWluJywnam9obnNvbicsJ3RydW1wJywnY2xpbnRvbicpLA0KICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCdPdGhlcnMnLCdKaWxsIFN0ZWluJywnR2FyeSBKb2huc29uJywnRG9uYWxkIEogVHJ1bXAnLCdIaWxsYXJ5IENsaW50b24nKSkgKw0KICBsYWJzKHggPSBOVUxMLCB5ID0gJ1BlcmNlbnQgb2YgVm90ZScpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50KSArDQogIGdndGl0bGUocGFzdGUwKCdQZXJjZW50IG9mIFZvdGUgYnkgQ291bnR5IH4gJyxmYWNldHRpbmdfdmFyaWFibGUpLCBzdWJ0aXRsZT0nMjAxNiBVU0EgUHJlc2lkZW50aWFsIEVsZWN0aW9uJykgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpKSArDQogIGZhY2V0X3dyYXAofmZjdCwgc2NhbGVzID0gJ2ZyZWVfeCcpDQoNCg0KYGBgDQoqIExldCdzIHRyeSBkaWZmZXJlbnQgd2F5cyBvZiBmYWNldHRpbmcuDQogICAgKyBIZXJlIHdlIGFyZSBsb29raW5nIGF0IHRoZSBpbXBhY3Qgb2YgZGlmZmVyZW50IHZhcmlhYmxlcyBvbiB0aGVpciB2b3RlIGZvciBUcnVtcC4gIEkndmUgYWxzbyBpbmNsdWRlZCBhIGRmIGZvciBpbmRpdmlkdWFsIHItc3F1YXJlZCB2YWx1ZXMsIGhlcmUuDQpgYGB7cn0NCnN0YXRlc19ieV9yZWdpb24gPC0gcmVhZF9jc3YoJy4vc3RhdGVzX2J5X3JlZ2lvbi5jc3YnKQ0KZGF0YTIwMTYgPC0gbGVmdF9qb2luKGRhdGEyMDE2LCBzZWxlY3Qoc3RhdGVzX2J5X3JlZ2lvbiwgLWBTdGF0ZSBDb2RlYCksIGJ5ID0gYygnU3RhdGVOYW1lJz0nU3RhdGUnKSkNCkRlbW9fRmFjdG9ycyA8LSBtdXRhdGUoZGF0YTIwMTYsIE1mZ0VtcENoYW5nZTE5ODBfMjAxNSA9IChNZmdFbXAyMDE1L1RvdGFsRW1wMjAxNSkgLSAoTWZnRW1wMTk4MC9Ub3RhbEVtcDE5ODApKSAlPiUgDQogIHNlbGVjdChDb3VudHksIHJEUlBjdCwgUmVnaW9uLCBNZmdFbXBDaGFuZ2UxOTgwXzIwMTUsIE5DSFNfVXJiYW5SdXJhbDIwMTMsIFRvdGFsUG9wdWxhdGlvbiwgTWVkaWFuQWdlLCBNZWRpYW5Ib3VzZWhvbGRJbmNvbWUsIFNpbXBzb25EaXZlcnNpdHlJbmRleCwgcHJvcFdoaXRlLCBwcm9wQmxhY2ssIHByb3BNZmcyMDE1LCBwcm9wSFMsIHByb3BNb3JlSFMsIHByb3BVbmVtcCwgcHJvcEVsZGVycywgcHJvcE5NYXJyaWVkKQ0KRGVtb19GYWN0b3JzJFJlZ2lvbjwtIGFzLmZhY3RvcihEZW1vX0ZhY3RvcnMkUmVnaW9uKQ0KDQpEZW1vX0ZhY3RvcnNfbSA8LSBtZWx0KHNlbGVjdChEZW1vX0ZhY3RvcnMsIC1OQ0hTX1VyYmFuUnVyYWwyMDEzKSwgaWQgPSBjKCdDb3VudHknLCdyRFJQY3QnKSkNCg0Kcl9zcXVhcmVkcyA8LSBkYXRhX2ZyYW1lKHZhcmlhYmxlID0gdW5pcXVlKERlbW9fRmFjdG9yc19tJHZhcmlhYmxlKSkNCnJfc3F1YXJlZHMkcl9zcXVhcmUgPC0gc2FwcGx5KHJfc3F1YXJlZHMkdmFyaWFibGUsIGZ1bmN0aW9uKGkpew0KICBwZXJjZW50X2Zvcm1hdCgpKHN1bW1hcnkobG0odW5saXN0KERlbW9fRmFjdG9yc1thcy5jaGFyYWN0ZXIoaSldKX5EZW1vX0ZhY3RvcnMkckRSUGN0KSkkci5zcXVhcmVkKQ0KfSkNCg0KRGVtb19GYWN0b3JzX20gPC0gbGVmdF9qb2luKERlbW9fRmFjdG9yc19tLCByX3NxdWFyZWRzLCBieT0ndmFyaWFibGUnKQ0KDQoNCmdncGxvdChEZW1vX0ZhY3RvcnNfbSwgYWVzKHg9dmFsdWUsIHk9ckRSUGN0KSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nKSArDQogIGZhY2V0X3dyYXAofnZhcmlhYmxlLCBzY2FsZXMgPSAnZnJlZV94JykNCg0KYGBgDQojIyNNYW51ZmFjdHVyaW5nIFZpc3VhbGl6YXRpb24NCmBgYHtyfQ0KDQojIHB1bGxlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9jcGhhbHBlcnQvY2Vuc3VzLXJlZ2lvbnMvYmxvYi9tYXN0ZXIvdXMlMjBjZW5zdXMlMjBidXJlYXUlMjByZWdpb25zJTIwYW5kJTIwZGl2aXNpb25zLmNzdg0Kc3RhdGVzX2J5X3JlZ2lvbiA8LSByZWFkX2NzdignLi9zdGF0ZXNfYnlfcmVnaW9uLmNzdicpDQpkYXRhMjAxNiA8LSBsZWZ0X2pvaW4oZGF0YTIwMTYsIHNlbGVjdChzdGF0ZXNfYnlfcmVnaW9uLCAtYFN0YXRlIENvZGVgKSwgYnkgPSBjKCdTdGF0ZU5hbWUnPSdTdGF0ZScpKQ0KRGVtb19GYWN0b3JzIDwtIG11dGF0ZShkYXRhMjAxNiwgTWZnRW1wQ2hhbmdlMTk4MF8yMDE1ID0gKE1mZ0VtcDIwMTUvVG90YWxFbXAyMDE1KSAtIChNZmdFbXAxOTgwL1RvdGFsRW1wMTk4MCksDQogICAgICAgICAgICAgICAgICAgICAgIHJlZ2lvbl9kaXZpc2lvbiA9IHBhc3RlKFJlZ2lvbiwnLScsRGl2aXNpb24pKSAlPiUNCiAgc2VsZWN0KENvdW50eSwgckRSUGN0LCBSZWdpb24sIHJlZ2lvbl9kaXZpc2lvbiwgTWZnRW1wQ2hhbmdlMTk4MF8yMDE1LCBOQ0hTX1VyYmFuUnVyYWwyMDEzLCBUb3RhbFBvcHVsYXRpb24sIE1lZGlhbkFnZSwNCiAgICAgICAgIE1lZGlhbkhvdXNlaG9sZEluY29tZSwgU2ltcHNvbkRpdmVyc2l0eUluZGV4LCBwcm9wV2hpdGUsIHByb3BCbGFjaywgcHJvcE1mZzIwMTUsIHByb3BIUywgcHJvcE1vcmVIUywgcHJvcFVuZW1wLA0KICAgICAgICAgcHJvcEVsZGVycywgcHJvcE5NYXJyaWVkKQ0KRGVtb19GYWN0b3JzJFJlZ2lvbjwtIGFzLmZhY3RvcihEZW1vX0ZhY3RvcnMkUmVnaW9uKQ0KRGVtb19GYWN0b3JzJHJlZ2lvbl9kaXZpc2lvbiA8LSBhcy5mYWN0b3IoRGVtb19GYWN0b3JzJHJlZ2lvbl9kaXZpc2lvbikNCg0KRGVtb19GYWN0b3JzX20yIDwtIG1lbHQoc2VsZWN0KERlbW9fRmFjdG9ycywgQ291bnR5LCByRFJQY3QsIE1mZ0VtcENoYW5nZTE5ODBfMjAxNSwgcHJvcFdoaXRlLCByZWdpb25fZGl2aXNpb24pLCANCiAgICAgICAgICAgICAgICAgICAgICAgIGlkID0gYygnQ291bnR5JywnckRSUGN0JywnTWZnRW1wQ2hhbmdlMTk4MF8yMDE1JykpDQoNCnJlZ2lvbmFsX21mZzwtZmlsdGVyKERlbW9fRmFjdG9yc19tMiwgdmFyaWFibGUgPT0gJ3JlZ2lvbl9kaXZpc2lvbicsICFpcy5uYShNZmdFbXBDaGFuZ2UxOTgwXzIwMTUpKSAlPiUgc2VsZWN0KC12YXJpYWJsZSkNCmdncGxvdChyZWdpb25hbF9tZmcsIGFlcyh4PU1mZ0VtcENoYW5nZTE5ODBfMjAxNSwgeT1yRFJQY3QpKSsNCiAgZ2VvbV9wb2ludCgpKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nKSsNCiAgZmFjZXRfd3JhcCh+dmFsdWUpDQoNCmdncGxvdChyZWdpb25hbF9tZmcsIGFlcyh4PXZhbHVlLCB5PU1mZ0VtcENoYW5nZTE5ODBfMjAxNSkpICsgDQogIGdlb21fYm94cGxvdCgpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQpEZW1vX0ZhY3RvcnM8LWxlZnRfam9pbihEZW1vX0ZhY3RvcnMsIG11dGF0ZShkYXRhMjAxNiwgQmxpbmREaXNhYmxlZFNTSV9wID0gQmxpbmREaXNhYmxlZFNTSSAvIFRvdGFsUG9wdWxhdGlvbikgDQogICAgICAgICAgICAgICAgICAgICAgICAlPiUgc2VsZWN0KENvdW50eSwgQmxpbmREaXNhYmxlZFNTSV9wKSkNCmBgYA0KDQojIyNNb2RlbHMNCmBgYHtyfQ0Kc3VtbWFyeShsbShyRFJQY3QgfiAgUmVnaW9uICsgcHJvcFdoaXRlICsgTkNIU19VcmJhblJ1cmFsMjAxMyArIHByb3BOTWFycmllZCwgRGVtb19GYWN0b3JzKSkNCmBgYA0KIyMjTWFudWZhY3R1cmluZyBEZWNsaW5lDQoqIFdoZXJlPyBXaXRoaW4gcmVnaW9uPw0KDQpgYGB7cn0NCmxpYnJhcnkoY2hvcm9wbGV0aHIpDQpsaWJyYXJ5KGdyaWRFeHRyYSkNCg0KZ3JvdXBfbWZnPC1mdW5jdGlvbih2YWx1ZSl7DQogIGlmKHZhbHVlIDwgLTAuNSkgJ0xvc3QgPjUwJScNCiAgZWxzZSBpZih2YWx1ZSA8IC0wLjQpICdMb3N0IDQwJS01MCUnDQogIGVsc2UgaWYodmFsdWUgPCAtMC4zKSAnTG9zdCAzMCUtNDAlJw0KICBlbHNlIGlmKHZhbHVlIDwgLTAuMikgJ0xvc3QgMjAlLTMwJScNCiAgZWxzZSBpZih2YWx1ZSA8IC0wLjEpICdMb3N0IDEwJS0yMCUnDQogIGVsc2UgaWYodmFsdWUgPCAwKSAnTG9zdCAwJS0xMCUnDQogIGVsc2UgJ0dhaW5lZCcNCn0NCg0KcmVnaW9uYWxfbWZnX2Nob3JvPC1mdW5jdGlvbihyZWdpb24pew0KICByZWdpb25hbF9tZmdfZiA8LSBmaWx0ZXIocmVnaW9uYWxfbWZnLCBncmVwbChyZWdpb24sIHZhbHVlKSkNCiAgcmVnaW9uYWxfbWZnX2YkdmFsdWU8LXNhcHBseShyZWdpb25hbF9tZmdfZiRNZmdFbXBDaGFuZ2UxOTgwXzIwMTUsIGdyb3VwX21mZykgJT4lIA0KICAgIGZhY3RvcihsZXZlbHMgPSBjKCdMb3N0ID41MCUnLCdMb3N0IDQwJS01MCUnLA0KICAgICAgICAgICAgICAgICAgICAgICdMb3N0IDMwJS00MCUnLCdMb3N0IDIwJS0zMCUnLA0KICAgICAgICAgICAgICAgICAgICAgICdMb3N0IDEwJS0yMCUnLCdMb3N0IDAlLTEwJScsDQogICAgICAgICAgICAgICAgICAgICAgJ0dhaW5lZCcsIG9yZGVyZWQgPSBUKSkNCiAgc3RhdGVzPC1maWx0ZXIoZGF0YTIwMTYsIENvdW50eSAlaW4lIHJlZ2lvbmFsX21mZ19mJENvdW50eSkkU3RhdGVOYW1lICU+JSB0b2xvd2VyKCkNCiAgDQogIGNvdW50eV9jaG9yb3BsZXRoKGRmID0gZGF0YV9mcmFtZShyZWdpb24gPSByZWdpb25hbF9tZmdfZiRDb3VudHksIHZhbHVlID0gcmVnaW9uYWxfbWZnX2YkdmFsdWUpLCBzdGF0ZV96b29tID0gc3RhdGVzKSsNCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCcjYjEwMDI2JywnI2UzMWExYycsJyNmYzRlMmEnLCcjZmQ4ZDNjJywnI2ZlYjI0YycsJyNmZWQ5NzYnLCcjZmZlZGEwJywnI2ZmZmZjYycpLCBkcm9wPUYpICsNCiAgICBnZ3RpdGxlKHJlZ2lvbikNCn0NCg0KU291dGggPC0gcmVnaW9uYWxfbWZnX2Nob3JvKCdTb3V0aCcpDQpNaWR3ZXN0IDwtIHJlZ2lvbmFsX21mZ19jaG9ybygnTWlkd2VzdCcpDQpXZXN0IDwtIHJlZ2lvbmFsX21mZ19jaG9ybygnV2VzdCcpDQpOb3J0aGVhc3QgPC0gcmVnaW9uYWxfbWZnX2Nob3JvKCdOb3J0aGVhc3QnKQ0KDQpncmlkLmFycmFuZ2UoV2VzdCwgTm9ydGhlYXN0LCBNaWR3ZXN0LCBTb3V0aCwgbnJvdz0yLCB0b3AgPSAnTWFudWZhY3R1cmluZyBKb2JzIExvc3QgMTk4MCAtIDIwMTUnKQ0KDQpgYGANCiMjI0JMUyBEYXRhDQoqIEkgcHVsbGVkIGluIGxhYm9yIGZvcmNlIGRhdGEgZnJvbSBCTFMsIGFuZCBqb2luZWQgaXQgdG8gb3VyIGRhdGFzZXQuDQoqIFRoZSBudW1iZXIgb2YgZGlzY291cmFnZWQgd29ya2VycyBieSBjb3VudHkgd2FzIG5vdCBhdmFpbGFibGUsIHNvIEkgdHJpZWQgdG8gYmFjayBpbnRvIHRoZSBudW1iZXIuDQogICAgKyBUaGVyZSBhcmUgc2lnbmlmaWNhbnQgcHJvYmxlbXMgd2l0aCB0aGUgd2F5IEkgZGlkIHRoaXMsIGJlY2F1c2UgaXQgZG9lc24ndCBhY2NvdW50IGZvciBzY2hvb2wgb3IgZGlzYWJpbGl0eSBvciBhbnl0aGluZyBlbHNlLg0KKiBJdCB0dXJucyBvdXQgaXQncyBub3QgdmVyeSBleHBsYW5hdG9yeS4NCg0KYGBge3J9DQpjb3VudHlfdW5lbXAgPC0gcmVhZF9jc3YoJ2NvdW50eV9sZXZlbF91bmVtcGxveW1lbnRfQkxTLmNzdicpDQpjb3VudHlfdW5lbXAgPC0gbXV0YXRlKGNvdW50eV91bmVtcCwgRklQUyA9IGFzLm51bWVyaWMocGFzdGUwKFN0YXRlRklQcyxDb3VudHlGSVBTKSkpDQpkYXRhMjAxNiA8LSBsZWZ0X2pvaW4oZGF0YTIwMTYsIGZpbHRlcihjb3VudHlfdW5lbXAsUGVyaW9kID09ICcxNi1Ob3YnKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KEZJUFMsIExhYm9yRm9yY2UsIEVtcGxveWVkLCBVbmVtcGxveWVkLCBVbmVtcGxveW1lbnRSYXRlKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBjKCdDb3VudHknID0gJ0ZJUFMnKSkNCmRhdGEyMDE2IDwtIG11dGF0ZShkYXRhMjAxNiwgV29ya2luZ19BZ2UgPSBUb3RhbFBvcHVsYXRpb24gLSBBZ2UwXzQgLSBBZ2U1XzkgLSBBZ2UxMF8xNCAtIEFnZTE1XzE5IC0gQWdlNjVfNzQgLSBBZ2U3NV84NCAtIEFnZTg1LA0KICAgICAgICAgICAgICAgICAgIERpc2NvdXJhZ2VkX3BvdGVudGlhbGx5ID0gV29ya2luZ19BZ2UgLSBMYWJvckZvcmNlLngsDQogICAgICAgICAgICAgICAgICAgcHJvcERpc2NvdXJhZ2VkID0gRGlzY291cmFnZWRfcG90ZW50aWFsbHkgLyBUb3RhbFBvcHVsYXRpb24pDQoNCkRlbW9fRmFjdG9ycyA8LSBsZWZ0X2pvaW4oRGVtb19GYWN0b3JzLCBzZWxlY3QoZGF0YTIwMTYsIENvdW50eSwgcHJvcERpc2NvdXJhZ2VkKSkNCg0Kc3VtbWFyeShsbShyRFJQY3QgfiAgQmxpbmREaXNhYmxlZFNTSV9wICsgcHJvcERpc2NvdXJhZ2VkICsgTWZnRW1wQ2hhbmdlMTk4MF8yMDE1LCBEZW1vX0ZhY3RvcnMpKQ0KYGBgDQoNCg==